﻿

using CsvHelper;
using HalconDotNet;
using LeaderCCSLaserUI.Models;
using LeaderCCSLaserUI.Services;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using MotionRobot.Models;
using netDxf.Entities;
using netDxf.Header;
using netDxf;
using Newtonsoft.Json;
using NLog;
using Prism.Commands;
using Prism.Services.Dialogs;
using RestSharp;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ViewROI;
using LeaderCCSLaserUI.Data;
using LeaderCCSLaserUI.Data.Extensions;

using LeaderCCSLaserUI.Common;

using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
using Prism.Regions;

namespace LeaderCCSLaserUI.ViewModels.Home
{
    public class LeftHandViewModel : NavigationViewModel
    {
        #region 变量
        
        private static Logger logger = LogManager.GetCurrentClassLogger();
        private readonly IGTSCardService gTSCard;
        private readonly IPLCService pLC;
        private readonly IHIKCameraService leftCamera, rightCamera;

        private readonly IGetBarcodeService getBarcodeService;
      
        private readonly IDialogService _dialogService;
        private CancellationTokenSource source0, source1, source2;
        bool XHomed = false, YHomed = false; bool XHomed2 = false;
        bool PauseFlag = false;
        private Param? systemParam;
        int otherFinishCount = 0; bool InitFinishFlag = false; bool otherLineFinish = false, otherLineFail = false;
        private double mz1SafePos, mz2SafePos, mz1UpDist, mxYRunSpeed, mzRunSpeed, mlineScanSpeed, mbornH, preDelay, vxyLimit, flyPreDelay, mFlyGrabPreDelay, mXMinDist, mZLimit;
        private double[,] powerLimit = new double[5, 3], speedLimit = new double[5, 3], focalLengthLimit = new double[5, 3];
        private MPoint initPoint,rightInitPoint;
        HTuple calibHomMat2D1, calibHomMat2D2;
        ConcurrentBag<VisionResult> VisionResultList;
        double vx1 = 0, vy1 = 0; VResult vresult = VResult.Null;
        string comparisonPath = string.Empty, imagePath = string.Empty;
        string CurrentBarcode = string.Empty;
        int calcToken = 0;
        ConcurrentBag<Comparison> mesRecords = new ConcurrentBag<Comparison>();
        private bool isVisionResultConfirm = false, isCameraScanBarcode = false, isDoubleAlBarControl = false;
        bool isGrabing = false;
        double leftCameraExposureTime = 100, rightCameraExposureTime = 100;
        bool started2 = false;
        HObject scanImage;
        double zDistUpLimit = 0, zDistLowLimit = 0;
        #endregion
        #region 属性
        #region halcon
        private HImage cameraIamge0;
        public HImage CameraIamge0
        {
            get { return cameraIamge0; }
            set { SetProperty(ref cameraIamge0, value); }
        }
        private bool cameraRepaint0;
        public bool CameraRepaint0
        {
            get { return cameraRepaint0; }
            set { SetProperty(ref cameraRepaint0, value); }
        }
        private ObservableCollection<ROI> cameraROIList0 = new ObservableCollection<ROI>();
        public ObservableCollection<ROI> CameraROIList0
        {
            get { return cameraROIList0; }
            set { SetProperty(ref cameraROIList0, value); }
        }
        private HObject cameraAppendHObject0;
        public HObject CameraAppendHObject0
        {
            get { return cameraAppendHObject0; }
            set { SetProperty(ref cameraAppendHObject0, value); }
        }
        private HMsgEntry cameraAppendHMessage0;
        public HMsgEntry CameraAppendHMessage0
        {
            get { return cameraAppendHMessage0; }
            set { SetProperty(ref cameraAppendHMessage0, value); }
        }
        private Tuple<string, object> cameraGCStyle0;
        public Tuple<string, object> CameraGCStyle0
        {
            get { return cameraGCStyle0; }
            set { SetProperty(ref cameraGCStyle0, value); }
        }
        #endregion
        private int stepNum;

        public int StepNum
        {
            get { return stepNum; }
            set { SetProperty(ref stepNum, value); }
        }
        private string messageStr;
        public string MessageStr
        {
            get { return messageStr; }
            set { SetProperty(ref messageStr, value); }
        }
        private int curCounter;
        public int CurCounter
        {
            get { return curCounter; }
            set { SetProperty(ref curCounter, value); }
        }
        private long totalCounter;
        public long TotalCounter
        {
            get { return totalCounter; }
            set { SetProperty(ref totalCounter, value); }
        }
        private double cycleTime;
        public double CycleTime
        {
            get { return cycleTime; }
            set { SetProperty(ref cycleTime, value); }
        }
        private string banci;
        public string Banci
        {
            get { return banci; }
            set { SetProperty(ref banci, value); }
        }
        private PlotModel plotModel1;
        public PlotModel PlotModel1
        {
            get { return plotModel1; }
            set { SetProperty(ref plotModel1, value); }
        }
        private string vehicleBarcode;
        public string VehicleBarcode
        {
            get { return vehicleBarcode; }
            set { SetProperty(ref vehicleBarcode, value); }
        }
        #endregion
        #region 命令
        private DelegateCommand testButtonCommand;
        public DelegateCommand TestButtonCommand =>
            testButtonCommand ?? (testButtonCommand = new DelegateCommand(ExecuteTestButtonCommand));

        void ExecuteTestButtonCommand()
        {
            //GTSCard.AxisHomeMove(gTSCard.A6);
            //using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
            //mdb.MParams.Add(new MParam { 
            //    Name = "LeftInit",
            //    Type = typeof(MPoint).Name,
            //    Value = JsonConvert.SerializeObject(systemParam.LeftInit, Formatting.Indented),
            //    Hand = 0
            //});
            //mdb.SaveChanges();
            //var aa = MFunc.LazerScript("192.168.106.16", "Connect");
            // addMessage(aa);
            //var r = await httpRestClient.ExecuteAsync(new BaseRequest { Method = Method.Post,Route = "Report/MachineOutputInit",
            //    Parameter = new
            //    {
            //        lineCode = 1,
            //        machineCode = 2,
            //        logCode = "1",
            //        logContent = "",
            //        logType = 1
            //    }
            //});
            //leftCamera.SetDir(false);
            //var ss = httpRestClient.BarcodeExecute(new BaseRequest { 
            //    Route = "find?site=3",
            //    Method = Method.Get
            //});


            //Task.Run(() =>
            //{


            //    System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
            //    {
            //        HOperatorSet.ReadImage(out var img, "D:\\111.jpg");
            //        DialogParameters param = new DialogParameters();
            //        param.Add("Image", img);
            //        param.Add("PointName", "222");
            //        _dialogService.ShowDialog("VisionAlarmDialog", param,arg =>
            //        {
            //            var row = arg.Parameters.GetValue<HTuple>("row");
            //            var column = arg.Parameters.GetValue<HTuple>("column");
            //        });
            //    }));


            //});
            //System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
            //ofd.Filter = "Dxf文件(*.dxf)|*.dxf|所有文件|*.*";
            //if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            //{
            //    // this check is optional but recommended before loading a DXF file
            //    DxfVersion dxfVersion = DxfDocument.CheckDxfFileVersion(ofd.FileName, out var isBinary);
            //    // netDxf is only compatible with AutoCad2000 and higher DXF version
            //    if (dxfVersion < DxfVersion.AutoCad2000) return;
            //    // load file
            //    DxfDocument dxf = DxfDocument.Load(ofd.FileName);
            //    var blocks = dxf.Inserts.Where(l => l.Layer.Name == "0");
            //    if (blocks.Any())
            //    {
            //        var blocklist = blocks.ToList();
            //    }
            //}
            //aggregator.SendMessage($"PartNum;{systemParam.PartList[systemParam.PartIndex]}", "MES");
            //addMessage(aaaa.ToString());
            //Type type = Type.GetType("LeaderCCSLaserUI.Models.VisionResult");

            //var MShapeModelParam = new ShapeModelParam();
            //MShapeModelParam.NumLevels = 3;
            //MShapeModelParam.AngleStart = -10;
            //MShapeModelParam.AngleEnd = 10;
            //MShapeModelParam.FileName = "";
            //MShapeModelParam.MinScore = 0.5;
            //string jsonString = JsonConvert.SerializeObject(MShapeModelParam, Formatting.Indented);
            //using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
            //var _mParam = mdb.VisionProjects.FirstOrDefault(m => m.Id == 1);
            //_mParam.Parameter = jsonString;
            //mdb.SaveChanges();
        }
        #endregion
        #region 导航
        public override void OnNavigatedTo(NavigationContext navigationContext)
        {
            LoadParam();
            LoadParamFromDB();
            LoadCameraParam();
            if (pLC.Connected)
            {
                source0 = new CancellationTokenSource();
                CancellationToken token = source0.Token;
                Task.Run(() => Run(token), token);
                addMessage("加载完成");
            }
            Task.Run(() => {
                Thread.Sleep(100);
                aggregator.SendMessage($"VehicleBarcode;{VehicleBarcode}","Run");
            });
        }
        #endregion
        #region 构造函数
        public LeftHandViewModel(IContainerProvider containerProvider) : base(containerProvider)
        {
            VisionResultList = new ConcurrentBag<VisionResult>();
            MessageStr = string.Empty;
            VehicleBarcode = string.Empty;
            HOperatorSet.GenEmptyObj(out scanImage);
            PlotModel1 = new PlotModel { Title = "激光功率(左)", TitleColor = OxyColor.FromRgb(32, 32, 32) };
            PlotModel1.PlotAreaBorderColor = OxyColor.FromRgb(32, 32, 32);
            PlotModel1.TextColor = OxyColor.FromRgb(32, 32, 32);
            PlotModel1.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, MajorGridlineStyle = LineStyle.Dot, Title = "时间", TicklineColor = OxyColor.FromRgb(32, 32, 32) });
            PlotModel1.Axes.Add(new LinearAxis { Position = AxisPosition.Left, MajorGridlineStyle = LineStyle.Dot, Title = "功率（W）", Maximum = 1000, TicklineColor = OxyColor.FromRgb(32, 32, 32) });
            PlotModel1.InvalidatePlot(true);

            gTSCard = containerProvider.Resolve<IGTSCardService>("GTSCard");
            pLC = containerProvider.Resolve<IPLCService>("PLC");
            leftCamera = containerProvider.Resolve<IHIKCameraService>("LeftCamera");
            rightCamera = containerProvider.Resolve<IHIKCameraService>("RightCamera");
            
            _dialogService = containerProvider.Resolve<IDialogService>();
            getBarcodeService = containerProvider.Resolve<IGetBarcodeService>();
            aggregator.ResgiterMessage(arg =>
            {
                switch (arg.Message)
                {
                    case "AppClose":
                        {
                            if (source0 != null)
                            {
                                source0.Cancel();
                            }
                            if (source1 != null)
                            {
                                source1.Cancel();
                            }
                            if (source2 != null)
                            {
                                source2.Cancel();
                            }
                        }
                        break;
                    default:
                        break;
                }
            });
            aggregator.ResgiterMessage(arg =>
            {
                if (arg.Message.Contains("FinishCount2"))
                {
                    var strs = arg.Message.Split(new char[] { ';' });
                    otherFinishCount = int.Parse(strs[1]);
                }
                else if (arg.Message.Contains("CalcToken1"))
                {
                    var strs = arg.Message.Split(new char[] { ';' });
                    calcToken = int.Parse(strs[1]);
                }
                else
                {
                    switch (arg.Message)
                    {
                        case "InitFinish":
                            InitFinishFlag = true;
                            break;
                        case "LineFinish2":
                            otherLineFinish = true;
                            break;
                        case "ReloadParam":
                            LoadParam();
                            LoadParamFromDB();
                            addMessage("更新参数");
                            break;
                        case "ReloadCameraParam":
                            LoadCameraParam();
                            break;
                        case "XHomed2":
                            XHomed2 = true;
                            break;
                        case "Started2":
                            started2 = true;
                            break;
                        case "LineFail2":
                            otherLineFail = true;
                            break;
                        case "GrabAction":
                            if (StepNum == 9 && !isGrabing)
                            {
                                addMessage("手动飞拍");
                                source2 = new CancellationTokenSource();
                                CancellationToken token2 = source2.Token;
                                isGrabing = true;
                                Task.Run(() => GrabAction(token2), token2).ContinueWith(arg => { 
                                    isGrabing = false;
                                    aggregator.SendMessage("GrabActionDone", "Run");
                                });
                            }
                            else
                            {
                                if (StepNum != 9)
                                {
                                    addMessage("未复位完成，不能飞拍");
                                }
                                if (isGrabing)
                                {
                                    addMessage("飞拍进行中，不响应重复指令");
                                }
                            }
                            break;
                        default:
                            break;
                    }
                }

            }, "Run");
            aggregator.ResgiterMessage(arg =>
            {
                try
                {
                    var _record = JsonConvert.DeserializeObject<Comparison>(arg.Message);
                    mesRecords.Add(_record);
                }
                catch { }
            }, "MES2");
            aggregator.ResgiterMessage(arg =>
            {
                try
                {
                    var strs = arg.Message.Split(new char[] { ';' });
                    bool r = strs[1].Substring(0).ToUpper().Contains("\"RESULT\":0") || strs[1].Substring(0).ToUpper().Contains("\"RESULT\":TRUE");
                    if (!r)
                    {
                        addMessage(strs[1]);
                    }
                    if (pLC.Connected)
                    {
                        if (r)
                        {
                            pLC.WriteMCoil(2582, true);
                        }
                        else
                        {
                            pLC.WriteMCoil(2583, true);
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (pLC.Connected)
                    {
                        pLC.WriteMCoil(2583, true);
                    }
                    addMessage(ex.Message);
                }
            }, "MESBack");

        }
        #endregion
        #region 功能函数
        private void addMessage(string str)
        {
            logger.Debug("L:" + str);
            string[] s = MessageStr.Split('\n');
            if (s.Length > 1000)
            {
                MessageStr = "";
            }
            if (MessageStr != "")
            {
                MessageStr += "\n";
            }
            MessageStr += DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + " " + str;
        }
        private void Run(CancellationToken token)
        {
            #region 变量
            int stepnum = 0;
            bool XAlarm = false, YAlarm = false, ZAlarm = false, X1Alarm = false, Y1Alarm = false, Z1Alarm = false, XDistAlarm = false; ;
            bool EMGButton = true, ResetButton = false, PauseButton = false, StartButton = false, SafeGrate = true;
            var axisX = gTSCard.A1; var axisY = gTSCard.A2; var axisZ = gTSCard.A3;
            var axisX1 = gTSCard.A5; var axisY1 = gTSCard.A6; var axisZ1 = gTSCard.A7;
            int cycleCount = 0;
            Stopwatch sw = new Stopwatch();
            bool XHomeFinishFlag = false, YHomeFinishFlag = false;
            XYZPoint curPoint = new XYZPoint(), rightCurPoint = new XYZPoint();
            Queue<XYZPoint> pcsQueue = new Queue<XYZPoint>();
            Queue<BarcodePoint> barQueue = new Queue<BarcodePoint>();
            BarcodePoint curBar = new BarcodePoint();
            int finishCount = 0; int weldPointsCount = 0;
            bool cameraGrabDone = false, cameraGrabResult = false; double dMarkSpeed = 0, ipg_power = 0, lzDist = 0; bool LazerDone = false;
            bool imageFailDone = false;int alarmDialogResult = 0;
            bool firstFlag = false;
            Stopwatch ctsw = new Stopwatch();
            bool imageCalcFinishFlag = false;
            bool start1 = false, start1flag = false;
            LineSeries s1 = new LineSeries();int plotIndex = 0;
            bool grabDone = false;
            bool isZControlStudy = false;
            
            #endregion
            #region 开机
            System.Threading.Thread.Sleep(2500);//开机延时2.5秒
            addMessage("请按\"复位\"按钮");
            aggregator.SendMessage("开机", "OEE");
            GTSCard.SetDo(gTSCard.A1.CardNo, 7, 0);
            GTSCard.SetDo(gTSCard.A1.CardNo, 8, 0);
            #endregion
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }
                try
                {
                    #region IO信号
                    var eMGButton = pLC.XCoils_X0[3] && pLC.XCoils_X0[7];
                    StartButton = pLC.XCoils_X0[0] || pLC.XCoils_X0[4];
                    var resetButton = pLC.XCoils_X0[1] || pLC.XCoils_X0[5];
                    var pauseButton = pLC.XCoils_X0[2] && pLC.XCoils_X0[6];
                    var safeGrate = pLC.XCoils_X0[24] && pLC.XCoils_X0[25] && pLC.XCoils_X0[26] && pLC.XCoils_X0[27];
                    var xAlarm = GTSCard.GetAxisAlarm(axisX);
                    var yAlarm = GTSCard.GetAxisAlarm(axisY);
                    var zAlarm = GTSCard.GetAxisAlarm(axisZ);
                    var x1Alarm = GTSCard.GetAxisAlarm(axisX1);
                    var y1Alarm = GTSCard.GetAxisAlarm(axisY1);
                    var z1Alarm = GTSCard.GetAxisAlarm(axisZ1);
                    if (EMGButton != eMGButton)
                    {
                        if (!eMGButton)
                        {
                            addMessage("急停按钮按下");
                        }
                        EMGButton = eMGButton;
                    }
                    if (PauseButton != pauseButton)
                    {
                        if (!pauseButton)
                        {
                            addMessage("停止按钮按下");
                            if (stepnum != -2)
                            {
                                aggregator.SendMessage("暂停", "OEE");
                            }
                        }
                        PauseButton = pauseButton;
                    }
                    if (SafeGrate != safeGrate)
                    {
                        if (!safeGrate)
                        {
                            addMessage("安全门打开");
                            if (stepnum != -2)
                            {                               
                                aggregator.SendMessage("暂停", "OEE");
                            }
                        }
                        SafeGrate = safeGrate;
                    }
                    if (XAlarm != xAlarm)
                    {
                        if (xAlarm)
                        {
                            if (pLC.Connected)
                            {
                                pLC.WriteMCoil(2562, true);
                            }
                            addMessage("X轴报警");
                            if (stepnum != -2)
                            {
                                aggregator.SendMessage("暂停", "OEE");
                            }
                        }
                        XAlarm = xAlarm;
                    }
                    if (YAlarm != yAlarm)
                    {
                        if (yAlarm)
                        {
                            if (pLC.Connected)
                            {
                                pLC.WriteMCoil(2562, true);
                            }
                            addMessage("Y轴报警");
                            if (stepnum != -2)
                            {
                               
                                aggregator.SendMessage("暂停", "OEE");
                            }
                        }
                        YAlarm = yAlarm;
                    }
                    if (ZAlarm != zAlarm)
                    {
                        if (zAlarm)
                        {
                            if (pLC.Connected)
                            {
                                pLC.WriteMCoil(2562, true);
                            }
                            addMessage("Z轴报警");
                            if (stepnum != -2)
                            {
                                aggregator.SendMessage("暂停", "OEE");
                            }
                        }
                        ZAlarm = zAlarm;
                    }
                    var _xDist = GTSCard.GetEnc(axisX) - GTSCard.GetEnc(axisX1);
                    var xDistAlarm = XHomed && XHomed2 && Math.Abs(_xDist) < mXMinDist;
                    if (XDistAlarm != xDistAlarm)
                    {
                        if (xDistAlarm)
                        {
                            GTSCard.AxisStop(axisX, 0);
                            addMessage("双头距离过近报警");
                            if (stepNum != -2)
                            {
                                aggregator.SendMessage("暂停", "OEE");
                            }
                        }
                        XDistAlarm = xDistAlarm;
                    }
                    if (!pauseButton || !safeGrate || xAlarm || yAlarm || zAlarm || x1Alarm || y1Alarm || z1Alarm || xDistAlarm)
                    {
                        PauseFlag = true;
                    }
                    else
                    {
                        if (PauseFlag)
                        {
                            if (resetButton)
                            {
                                PauseFlag = false;
                                if (stepnum != -2)
                                {
                                    if (stepnum < 9)
                                    {

                                    }
                                    else if (stepnum == 9)
                                    {
                                        aggregator.SendMessage("复位完成", "OEE");
                                    }
                                    else
                                    {
                                        
                                        aggregator.SendMessage("运行", "OEE");
                                    }
                                }
                            }
                        }
                    }
                    var m2520 = pLC.ReadMCoils(2520, 2);
                    var _start = m2520[0] && m2520[1];
                    if (start1 != _start)
                    {
                        if (_start)
                        {
                            start1flag = true;
                        }
                        start1 = _start;
                    }
                    if (!m2520[0] || !m2520[1])
                    {
                        start1flag = false;
                    }
                    #endregion
                    #region 外循环
                    if (!EMGButton && stepnum >= 0)
                    {
                        if (source1 != null)
                        {
                            source1.Cancel();
                        }
                        if (source2 != null)
                        {
                            source2.Cancel();
                        }
                        ResetAction();
                        sw.Stop();
                        finishCount = 0;
                        isGrabing = false;
                        otherFinishCount = 0;
                        InitFinishFlag = false;
                        firstFlag = false;
                        stepnum = -2;
                        pLC.WriteMCoil(2578, false);
                        pLC.WriteMCoil(2572, false);
                        pLC.WriteMCoil(2562, false);
                        pLC.WriteMCoil(2560, false);
                        aggregator.SendMessage("EMG", "Run");
                        aggregator.SendMessage("急停", "OEE");
                        leftCamera.StopGrabe();
                        rightCamera.StopGrabe();
                    }
                    #endregion
                    #region 流程
                    switch (stepnum)
                    {
                        #region 急停
                        case -2:
                            if (EMGButton)
                            {
                                addMessage("请安\"复位\"按钮");
                                stepnum = 0;
                                
                            }
                            break;
                        #endregion
                        #region 复位
                        case 0:
                            if (ResetButton != resetButton)
                            {
                                if (resetButton)
                                {
                                    stepnum = 1;
                                }
                                ResetButton = resetButton;
                            }
                            break;
                        case 1:
                            if (!PauseFlag)
                            {
                                //励磁
                                GTSCard.ServoOn(axisZ);
                                sw.Restart();
                                stepnum = 2;
                            }
                            break;
                        case 2:
                            if (!PauseFlag)
                            {
                                if (sw.Elapsed.TotalSeconds > 2)
                                {
                                    sw.Stop();
                                    //把编码器值复制到规划值
                                    GTSCard.AxisPosSet(axisX, GTSCard.GetEnc(axisX));
                                    GTSCard.AxisPosSet(axisY, GTSCard.GetEnc(axisY));
                                    GTSCard.AxisPosSet(axisZ, GTSCard.GetEnc(axisZ));
                                    stepnum = 3;
                                }
                            }
                            break;
                        case 3:
                            if (!PauseFlag)
                            {
                                GTSCard.AxisPosMove(ref axisZ, mz1SafePos, mzRunSpeed / 5);
                                stepnum = 4;
                            }
                            break;
                        case 4:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisZ))
                                {
                                    GTSCard.SetEnc(0, 9, 0);//辅助编码器归零
                                    GTSCard.ServoOn(axisX);
                                    GTSCard.ServoOn(axisY);
                                    stepnum = 5;
                                    sw.Restart();
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisZ, 0);
                                stepnum = 3;
                            }
                            break;
                        case 5://Y轴复位和X轴回原点
                            if (!PauseFlag)
                            {
                                if (sw.Elapsed.TotalSeconds > 2)
                                {
                                    sw.Stop();
                                    GTSCard.AxisPosSet(axisX, GTSCard.GetEnc(axisX));
                                    GTSCard.AxisPosSet(axisY, GTSCard.GetEnc(axisY));
                                    source1 = new CancellationTokenSource();
                                    CancellationToken token1 = source1.Token;
                                    XHomeFinishFlag = false;
                                    Task.Run(() => XHome(token1), token1).ContinueWith(t => XHomeFinishFlag = true);
                                    YHomeFinishFlag = false;
                                    Task.Run(() => YHome(token1), token1).ContinueWith(t => YHomeFinishFlag = true);
                                    stepnum = 6;
                                }
                            }
                            break;
                        case 6:
                            if (!PauseFlag)
                            {
                                if (XHomeFinishFlag && YHomeFinishFlag)
                                {
                                    aggregator.SendMessage("XHomed1", "Run");
                                    stepnum = 7;
                                }
                            }
                            break;
                        case 7:
                            if (!PauseFlag)
                            {
                                GTSCard.AxisPosMove(ref axisX, initPoint.X, mxYRunSpeed / 5);
                                GTSCard.AxisPosMove(ref axisY, initPoint.Y, mxYRunSpeed / 5);
                                GTSCard.AxisPosMove(ref axisZ, initPoint.Z, mzRunSpeed / 5);
                                stepnum = 8;
                            }
                            break;
                        case 8:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY)
                                    && GTSCard.AxisPosMoveCheckDone(axisZ))
                                {
                                    Debug.WriteLine("复位完成");
                                    aggregator.SendMessage("复位完成", "OEE");
                                    pLC.WriteMCoil(2578, true);
                                    pLC.WriteMCoil(2572, true);
                                   
                                    stepnum = 9;
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisX, 0);
                                GTSCard.AxisStop(axisY, 0);
                                GTSCard.AxisStop(axisZ, 0);
                                stepnum = 7;
                            }
                            break;
                        #endregion
                        #region 启动
                        case 9:
                            if (!PauseFlag)
                            {
                                var m2540 = pLC.ReadMCoils(2540, 1);
                                if (m2540[0])
                                {
                                    pLC.WriteMCoil(2540, false);
                                    if (getBarcodeService.GetBarcode())
                                    {
                                        bool r = false;
                                        for (int i = 0; i < getBarcodeService.Barcodes.Length; i++)
                                        {
                                            addMessage(getBarcodeService.Barcodes[i]);
                                            if (getBarcodeService.Barcodes[i] != string.Empty)
                                            {
                                                r = true;
                                                break;
                                            }
                                        }
                                        if (r)
                                        {
                                            pLC.WriteMCoil(2581, true);
                                            addMessage("获取条码成功");
                                        }
                                        else
                                        {
                                            pLC.WriteMCoil(2581, false);
                                            addMessage("获取条码为空");
                                        }

                                    }
                                    else
                                    {
                                        addMessage("获取条码失败");
                                        pLC.WriteMCoil(2581, false);
                                    }

                                    for (int i = 0; i < getBarcodeService.Barcodes.Length; i++)
                                    {
                                        if (getBarcodeService.Barcodes[i] != string.Empty)
                                        {
                                            aggregator.SendMessage($"进站校验;{GetBarcode(i)}", "MES");
                                        }
                                    }

                                    pLC.WriteMCoil(2580, true);
                                }

                                //if ((m2520[0] && m2520[1] && firstFlag || StartButton) && InitFinishFlag)
                                if (start1flag && InitFinishFlag)
                                {
                                    stepnum = 10;
                                }
                            }
                            break;
                        case 10009:
                            if (!PauseFlag)
                            {
                                if (ResetButton != resetButton)
                                {
                                    if (resetButton)
                                    {
                                        stepnum = 9;
                                    }
                                    ResetButton = resetButton;
                                }
                            }
                            break;
                        case 10:
                            if (!PauseFlag)
                            {
                                double curAEnc = GTSCard.GetEnc(0, 9) / 1000;
                                if (Math.Abs(curAEnc) <= 0.1)//检查探高
                                {
                                    
                                    addMessage("开始工作");
                                    aggregator.SendMessage("开始工作", "OEE");
                                    started2 = false;
                                    aggregator.SendMessage("Start2", "Run");
                                    mesRecords.Clear();
                                    firstFlag = true;
                                    imageFailDone = false;
                                    otherFinishCount = 0;
                                    calcToken = 0;
                                    VehicleBarcode = string.Empty;
                                    VisionResultList.Clear();
                                    System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                    {
                                        aggregator.SendMessage("Reset", "Run");
                                    }));
                                    InitFinishFlag = false;
                                    pLC.WriteMCoil(2520, false);
                                    pLC.WriteMCoil(2521, false);
                                    start1flag = false;
                                    ctsw.Restart();
                                    otherLineFinish = false;
                                    otherLineFail = false;
                                    gTSCard.ImageList.Clear();
                                    CameraIamge0 = null;
                                    CameraAppendHMessage0 = null;
                                    if (!isGrabing)
                                    {
                                        addMessage("拍照正忙");
                                    }
                                    stepnum = 11;

                                    pLC.WriteMCoil(2578, false);
                                }
                                else
                                {
                                    addMessage($"探高异常:{curAEnc:f3}");
                                    stepnum = 10009;
                                }
                            }
                            break;
                        case 11:
                            if (!PauseFlag)
                            {
                                if (!isGrabing && started2)
                                {
                                    if (isCameraScanBarcode)
                                    {
                                        stepnum = 400;
                                    }
                                    else
                                    {

                                        aggregator.SendMessage($"YD进站校验;{string.Join('|', getBarcodeService.Barcodes)}", "MES");
                                        //不扫码
                                        if (VehicleBarcode != string.Empty)
                                        {
                                            VehicleBarcode = string.Empty;
                                            SaveVehicleBarcode(VehicleBarcode);
                                        }
                                        if (systemParam.IsUseVision)
                                        {                                    
                                            stepnum = 500;
                                        }
                                        else
                                        {
                                            stepnum = 1100;
                                        }
                                    }
                                }
                            }
                            break;
                        #endregion
                        #region 扫码
                        case 400:
                            if (!PauseFlag)
                            {
                                barQueue.Clear();
                                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                                var barPoints = mdb.BarcodePoints.Where(p => p.Id > 0);
                                if (barPoints.Any())
                                {
                                    barPoints.ToList().ForEach(p => 
                                    {
                                        barQueue.Enqueue(p);
                                    });
                                }
                                var vechileBarPoint = mdb.BarcodePoints.FirstOrDefault(p => p.Kind == 1);
                                if (vechileBarPoint == null)
                                {
                                    //扫码，但是不扫载具码
                                    if (VehicleBarcode != string.Empty)
                                    {
                                        VehicleBarcode = string.Empty;
                                        SaveVehicleBarcode(VehicleBarcode);
                                    }
                                }
                                stepnum = 401;
                            }
                            break;
                        case 401:
                            if (!PauseFlag)
                            {
                                if (barQueue.TryPeek(out var _bar))
                                {
                                    curBar = barQueue.Dequeue();
                                    stepnum = 402;
                                }
                                else
                                {
                                    //完成
                                    aggregator.SendMessage($"YD进站校验;{string.Join('|', getBarcodeService.Barcodes)}", "MES");
                                    stepnum = 420;
                                }
                            }
                            break;
                        case 402:
                            if (!PauseFlag)
                            {
                                if (curBar.Hand == 0)
                                {
                                    GTSCard.AxisPosMove(ref axisX, curBar.X, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisY, curBar.Y, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisZ, curBar.Z, mzRunSpeed);
                                    GTSCard.AxisPosMove(ref axisX1, rightInitPoint.X, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisY1, rightInitPoint.Y, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisZ1, rightInitPoint.Z, mzRunSpeed);
                                    GTSCard.SetDo(axisX.CardNo, 7, (short)(curBar.UseLight1 ? 0 : 1));
                                    GTSCard.SetDo(axisX.CardNo, 8, (short)(curBar.UseLight2 ? 0 : 1));
                                }
                                else
                                {
                                    GTSCard.AxisPosMove(ref axisX, initPoint.X, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisY, initPoint.Y, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisZ, initPoint.Z, mzRunSpeed);
                                    GTSCard.AxisPosMove(ref axisX1, curBar.X, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisY1, curBar.Y, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisZ1, curBar.Z, mzRunSpeed);
                                    GTSCard.SetDo(axisX.CardNo, 14, (short)(curBar.UseLight1 ? 0 : 1));
                                    GTSCard.SetDo(axisX.CardNo, 15, (short)(curBar.UseLight2 ? 0 : 1));
                                }
                                stepnum = 403;
                            }
                            break;
                        case 403:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY)
                                    && GTSCard.AxisPosMoveCheckDone(axisZ) &&
                                    GTSCard.AxisPosMoveCheckDone(axisX1) && GTSCard.AxisPosMoveCheckDone(axisY1)
                                    && GTSCard.AxisPosMoveCheckDone(axisZ1))
                                {
                                    sw.Restart();
                                    stepnum = 404;
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisX, 0);
                                GTSCard.AxisStop(axisY, 0);
                                GTSCard.AxisStop(axisZ, 0);
                                GTSCard.AxisStop(axisX1, 0);
                                GTSCard.AxisStop(axisY1, 0);
                                GTSCard.AxisStop(axisZ1, 0);
                                stepnum = 402;
                            }
                            break;
                        case 404:
                            if (!PauseFlag)
                            {
                                if (sw.Elapsed.TotalSeconds > flyPreDelay)
                                {
                                    stepnum = 405;
                                }
                            }
                            break;
                        case 405:
                            if (!PauseFlag)
                            {
                                if (curBar.Hand == 0)
                                {
                                    grabDone = false;
                                    leftCamera.ImageQueue.Clear();
                                    leftCamera.SetTriggerMode(0);
                                    leftCamera.SetExposureTime((float)curBar.ExposureTime);
                                    leftCamera.StartGrabe();
                                    Task.Run(() =>
                                    {
                                        int mIndex = 0;
                                        while (mIndex < 1)
                                        {
                                            HObject? hObj;
                                            if (leftCamera.ImageQueue.TryPeek(out hObj))
                                            {
                                                leftCamera.ImageQueue.TryDequeue(out scanImage);
                                                mIndex++;
                                            }
                                        }
                                    }).ContinueWith(t => { leftCamera.StopGrabe(); grabDone = true; });
                                }
                                else
                                {
                                    grabDone = false;
                                    rightCamera.ImageQueue.Clear();
                                    rightCamera.SetTriggerMode(0);
                                    rightCamera.SetExposureTime((float)curBar.ExposureTime);
                                    rightCamera.StartGrabe();
                                    Task.Run(() => {
                                        int mIndex = 0;
                                        while (mIndex < 1)
                                        {
                                            HObject? hObj;
                                            if (rightCamera.ImageQueue.TryPeek(out hObj))
                                            {
                                                rightCamera.ImageQueue.TryDequeue(out scanImage);
                                                mIndex++;
                                            }
                                        }
                                    }).ContinueWith(t => { rightCamera.StopGrabe(); grabDone = true; });
                                }
                                stepnum = 406;
                            }
                            break;
                        case 406:
                            if (!PauseFlag)
                            {
                                if (grabDone)
                                {
                                    grabDone = false;
                                    try
                                    {
                                        HOperatorSet.CreateDataCode2dModel("QR Code", new HTuple(), new HTuple(), out var DataCodeHandle);
                                        HOperatorSet.SetDataCode2dParam(DataCodeHandle, "polarity", "any");
                                        HOperatorSet.SetDataCode2dParam(DataCodeHandle, "string_encoding", "locale");
                                        HOperatorSet.SetDataCode2dParam(DataCodeHandle, "timeout", 200);
                                        
                                        HOperatorSet.GenRectangle1(out var rec1, curBar.Rec1Row1, curBar.Rec1Column1, curBar.Rec1Row2, curBar.Rec1Column2);
                                        
                                        HOperatorSet.ReduceDomain(scanImage, rec1, out var imageReduced);
                                        HOperatorSet.FindDataCode2d(imageReduced, out var symbolXLD1, DataCodeHandle, new HTuple(), new HTuple(), out var ResultHandles, out var DecodedDataStrings);
                                        HOperatorSet.ClearDataCode2dModel(DataCodeHandle);
                                        imageReduced.Dispose();
                                        if (DecodedDataStrings.TupleLength() > 0)
                                        {
                                            string barcode = DecodedDataStrings.TupleSelect(0).S.Replace(" ",string.Empty);
                                            addMessage($"扫到条码:{curBar.ProductIndex + 1}:{barcode}");
                                            switch ((BarcodeEnum)curBar.Kind)
                                            {
                                                case BarcodeEnum.产品码:
                                                    {
                                                        getBarcodeService.SetBarcode(barcode, curBar.ProductIndex);
                                                    }
                                                    break;
                                                case BarcodeEnum.载具码:
                                                    {
                                                        VehicleBarcode = barcode;
                                                        SaveVehicleBarcode(VehicleBarcode);
                                                        aggregator.SendMessage($"VehicleBarcode;{VehicleBarcode}", "Run");
                                                    }
                                                    break;
                                                case BarcodeEnum.FPC码:
                                                    break;
                                                default:
                                                    break;
                                            }                                         
                                            //扫码成功
                                            stepnum = 401;
                                        }
                                        else
                                        {
                                            //扫码失败
                                            stepnum = 407;
                                        }

                                        System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                        {
                                            CameraIamge0 = new HImage(scanImage);
                                            CameraGCStyle0 = new Tuple<string, object>("Color", "cornflower blue");
                                            CameraAppendHObject0 = rec1;
                                            if (DecodedDataStrings.TupleLength() > 0)
                                            {
                                                CameraGCStyle0 = new Tuple<string, object>("Color", "green");
                                                CameraAppendHObject0 = symbolXLD1;
                                                CameraAppendHMessage0 = new HMsgEntry(DecodedDataStrings.TupleSelect(0).S, 10, 10, "magenta", "window", "box", "false", 24, "mono", "true", "false");
                                            }
                                            else
                                            {
                                                CameraAppendHMessage0 = new HMsgEntry($"NG", 40, 40, "orange red", "window", "box", "false", 24, "mono", "true", "false");
                                            }
                                        }));
                                    }
                                    catch (Exception ex)
                                    {
                                        addMessage(ex.Message);
                                        //扫码失败
                                        stepnum = 407;
                                    }
                                }
                            }
                            break;
                        case 407:
                            if (!PauseFlag)
                            {
                                imageFailDone = false;
                                if (pLC.Connected)
                                {
                                    pLC.WriteMCoil(2560, true);
                                }
                                System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                {
                                    DialogParameters param = new DialogParameters();
                                    param.Add("Message", "扫码失败");
                                    _dialogService.Show("MessageAlarmDialog", param, arg =>
                                    {
                                        imageFailDone = true;
                                    });
                                }));
                                stepnum = 408;
                            }
                            break;
                        case 408:
                            if (!PauseFlag)
                            {
                                if (imageFailDone)
                                {
                                    imageFailDone = false;
                                    if (pLC.Connected)
                                    {
                                        pLC.WriteMCoil(2560, false);
                                    }
                                    stepnum = 405;
                                }
                            }
                            break;
                        case 420:
                            if (!PauseFlag)
                            {
                                if (systemParam.IsUseVision)
                                {
                                    aggregator.SendMessage("BarcodeScanDone1", "Run");
                                    stepnum = 500;
                                }
                                else
                                {
                                    stepnum = 421;
                                }
                            }
                            break;
                        case 421:
                            if (!PauseFlag)
                            {
                                GTSCard.AxisPosMove(ref axisX, initPoint.X, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisY, initPoint.Y, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisZ, initPoint.Z, mzRunSpeed);
                                GTSCard.AxisPosMove(ref axisX1, rightInitPoint.X, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisY1, rightInitPoint.Y, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisZ1, rightInitPoint.Z, mzRunSpeed);
                                stepnum = 422;
                            }
                            break;
                        case 422:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY)
                                 && GTSCard.AxisPosMoveCheckDone(axisZ) &&
                                 GTSCard.AxisPosMoveCheckDone(axisX1) && GTSCard.AxisPosMoveCheckDone(axisY1)
                                 && GTSCard.AxisPosMoveCheckDone(axisZ1))
                                {
                                    aggregator.SendMessage("BarcodeScanDone1", "Run");
                                    stepnum = 1100;
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisX, 0);
                                GTSCard.AxisStop(axisY, 0);
                                GTSCard.AxisStop(axisZ, 0);
                                GTSCard.AxisStop(axisX1, 0);
                                GTSCard.AxisStop(axisY1, 0);
                                GTSCard.AxisStop(axisZ1, 0);
                                stepnum = 421;
                            }
                            break;
                        #endregion
                        #region 飞拍
                        case 500:
                            if (!PauseFlag)
                            {
                                source2 = new CancellationTokenSource();
                                CancellationToken token2 = source2.Token;
                                isGrabing = true;
                                Task.Run(() => GrabAction(token2), token2).ContinueWith(arg => { isGrabing = false; });
                                stepnum = 501;
                            }
                            break;
                        case 501:
                            if (!PauseFlag)
                            {
                                if (!isGrabing)
                                {
                                    stepnum = 600;
                                }
                            }
                            break;
                        case 600:
                            if (!PauseFlag)
                            {
                                aggregator.SendMessage("MoveToLineStart", "Run");//右侧开始计算
                                #region 存图1
                                Task.Run(() =>
                                {
                                    string dirpath = Path.Combine(imagePath, systemParam.PartList[systemParam.PartIndex], DateTime.Now.ToString("yyyyMMddHHmmss"));
                                    Directory.CreateDirectory(dirpath);
                                    foreach (var item in gTSCard.ImageList)
                                    {
                                        try
                                        {
                                            HOperatorSet.WriteImage(item.MImage, "jpeg", 0, Path.Combine(dirpath, $"{DateTime.Now:yyyyMMddHHmmss}_{item.Kind}_{item.CameraHand}_{item.Track}_{item.ImagePcsOrder}.jpg"));
                                        }
                                        catch (Exception ex)
                                        {
                                            addMessage(ex.Message);
                                        }
                                    }
                                });
                                #endregion
                                #region 计算图1
                                imageCalcFinishFlag = false;
                                Task.Run(() =>
                                {
                                    using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                                    var _points = mdb.XYZRPoints.Where(p => p.Hand == 0 && p.IsUse).OrderBy(p => p.PcsOrder);

                                    if (_points.Any())
                                    {
                                        _points.ToList().ForEach(p =>
                                        {
                                            var visionPcs = mdb.VisionPoints.FirstOrDefault(v => v.Hand == 0 && v.PcsOrder == p.PcsOrder);
                                            if (visionPcs != null)
                                            {
                                                var flyimage = gTSCard.ImageList.FirstOrDefault(img => img.CameraHand == visionPcs.CameraHand && img.Kind == visionPcs.ImageKind && img.Track == visionPcs.Track && img.ImagePcsOrder == visionPcs.ImagePcsOrder);
                                                if (flyimage != null)
                                                {
                                                    //0:未做模板 1:没找到 2:超限 200:PASS
                                                    VisionResult vresult = new VisionResult();
                                                    vresult.PcsOrder = p.PcsOrder;
                                                    vresult.r_name = p.Name;
                                                    while (calcToken % 2 != 0 && calcToken < 999)
                                                    {
                                                        System.Threading.Thread.Sleep(100);
                                                    }
                                                    calcToken++;
                                                    try
                                                    {
                                                        HOperatorSet.CropPart(flyimage.MImage, out var imagePart, visionPcs.Rec1Row1, visionPcs.Rec1Column1, visionPcs.Rec1Column2 - visionPcs.Rec1Column1, visionPcs.Rec1Row2 - visionPcs.Rec1Row1);
                                                        vresult.r_image = imagePart;
                                                        
                                                        VisionAction(visionPcs.ScriptFileName, imagePart, visionPcs.ModelKind, out var r_row, out var r_column, out var r_angle, out var result);
                                                        bool rflag = result.I == 1 && r_row.TupleLength() > 0 && r_column.TupleLength() > 0 && r_angle.TupleLength() > 0;
                                                        if (rflag)
                                                        {
                                                            
                                                            HOperatorSet.VectorAngleToRigid(visionPcs.ST_X, visionPcs.ST_Y, visionPcs.ST_Angle, r_row, r_column, r_angle, out var homMat2d);
                                                            HOperatorSet.AffineTransPoint2d(homMat2d, visionPcs.Target_X, visionPcs.Target_Y, out var trow1, out var tcolumn1);

                                                            HTuple _calc_qx, _calc_qy;
                                                            if (visionPcs.CameraHand == 0)
                                                            {
                                                                HOperatorSet.AffineTransPoint2d(calibHomMat2D1, visionPcs.Rec1Row1 + trow1, visionPcs.Rec1Column1 + tcolumn1, out _calc_qx, out _calc_qy);
                                                            }
                                                            else
                                                            {
                                                                HOperatorSet.AffineTransPoint2d(calibHomMat2D2, visionPcs.Rec1Row1 + trow1, visionPcs.Rec1Column1 + tcolumn1, out _calc_qx, out _calc_qy);
                                                            }

                                                            var calibPoint = visionPcs.CameraHand == 0 ? systemParam.LeftCameraCalib : systemParam.RightCameraCalib;
                                                            var flypoint = mdb.FlyGrabPoints.FirstOrDefault(fly => fly.Hand == visionPcs.CameraHand && fly.Kind == visionPcs.ImageKind && fly.Track == visionPcs.Track && fly.PcsOrder == visionPcs.ImagePcsOrder);
                                                            if (flypoint != null)
                                                            {
                                                                var calc_qx = _calc_qx + flypoint.X - calibPoint.X;
                                                                var calc_qy = _calc_qy + flypoint.Y - calibPoint.Y;
                                                                double deltaX = (p.X - calc_qx.D) * -1;
                                                                double deltaY = (p.Y - calc_qy.D) * -1;
                                                                double deltaAngle = ((visionPcs.ST_Angle - r_angle) * -1).TupleDeg().D;
                                                                if (Math.Abs(deltaX) > vxyLimit || Math.Abs(deltaY) > vxyLimit)
                                                                {
                                                                    vresult.result = VResult.Limit;
                                                                    addMessage($"{p.Name}用模板{visionPcs.ModelKind}偏差超限! ΔX{deltaX:f1}mm,ΔY{deltaY:f1}mm");
                                                                }
                                                                else
                                                                {
                                                                    vresult.r_row = trow1;
                                                                    vresult.r_column = tcolumn1;

                                                                    vresult.r_baserow = r_row;
                                                                    vresult.r_basecolumn = r_column;


                                                                    vresult.result = VResult.PASS;
                                                                    vresult.deltaX = deltaX;
                                                                    vresult.deltaY = deltaY;
                                                                    vresult.deltaAngle = deltaAngle;
                                                                }
                                                            }
                                                            else
                                                            {
                                                                vresult.result = VResult.NG;
                                                            }

                                                        }
                                                        else
                                                        {
                                                            vresult.result = VResult.NG;
                                                        }
                                                    }
                                                    catch (Exception ex)
                                                    {
                                                        vresult.result = VResult.NG;
                                                        addMessage(ex.Message);
                                                    }
                                                    VisionResultList.Add(vresult);
                                                    //addMessage($"{visionPcs.CameraHand}_{visionPcs.Track}_{visionPcs.ImagePcsOrder}添加数据");
                                                    aggregator.SendMessage($"CalcToken2;{calcToken}", "Run");
                                                }
                                                else
                                                {
                                                    addMessage($"{visionPcs.CameraHand}_{visionPcs.Track}_{visionPcs.ImagePcsOrder}无图像");
                                                }
                                            }
                                            else
                                            {
                                                addMessage($"{p.PcsOrder}未设置视觉数据");
                                            }
                                        });

                                    }
                                    aggregator.SendMessage($"CalcToken2;1000", "Run");
                                }).ContinueWith(arg => { imageCalcFinishFlag = true; });
                                #endregion
                                stepnum = 620;//飞拍完成
                            }
                            break;
                        case 620:
                            if (!PauseFlag)
                            {
                                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                                var leftPoints = mdb.XYZRPoints.Where(p => p.Hand == 0).OrderBy(p => p.PcsOrder);
                                if (leftPoints.Any())
                                {
                                    curPoint = leftPoints.ToArray()[0];
                                }
                                else
                                {
                                    curPoint = new XYZPoint { 
                                        X = initPoint.X,
                                        Y = initPoint.Y,
                                        Z = mz1SafePos
                                    };
                                }
                                var rightPoints = mdb.XYZRPoints.Where(p => p.Hand == 1).OrderBy(p => p.PcsOrder);
                                if (rightPoints.Any())
                                {
                                    rightCurPoint = rightPoints.ToArray()[0];
                                }
                                else
                                {
                                    rightCurPoint = new XYZPoint
                                    {
                                        X = rightInitPoint.X,
                                        Y = rightInitPoint.Y,
                                        Z = mz2SafePos
                                    };
                                }
                                stepnum = 621;
                            }
                            break;
                        case 621:
                            if (!PauseFlag) 
                            {
                                GTSCard.AxisPosMove(ref axisX, curPoint.X, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisY, curPoint.Y, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisZ, mz1SafePos, mzRunSpeed);
                                GTSCard.AxisPosMove(ref axisX1, rightCurPoint.X, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisY1, rightCurPoint.Y, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisZ1, mz2SafePos, mzRunSpeed);
                                stepnum = 622;
                            }
                            break;
                        case 622:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY)
                                 && GTSCard.AxisPosMoveCheckDone(axisZ) &&
                                 GTSCard.AxisPosMoveCheckDone(axisX1) && GTSCard.AxisPosMoveCheckDone(axisY1)
                                 && GTSCard.AxisPosMoveCheckDone(axisZ1))
                                {
                                    aggregator.SendMessage("CameraGrabDone1", "Run");//左侧动完，右侧可以移动
                                    stepnum = 1007;
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisX, 0);
                                GTSCard.AxisStop(axisY, 0);
                                GTSCard.AxisStop(axisZ, 0);
                                GTSCard.AxisStop(axisX1, 0);
                                GTSCard.AxisStop(axisY1, 0);
                                GTSCard.AxisStop(axisZ1, 0);
                                stepnum = 621;
                            }
                            break;
                        case 1007:
                            if (!PauseFlag)
                            {
                                if (isVisionResultConfirm)
                                {
                                    stepnum = 1020;
                                }
                                else
                                {
                                    aggregator.SendMessage("LineFinish1", "Run");
                                    stepnum = 1008;
                                }
                            }
                            break;
                        case 1008:
                            if (!PauseFlag)
                            {
                                if (otherLineFail)
                                {
                                    otherLineFail = false;
                                    stepnum = 1022;
                                }
                                else if (otherLineFinish)
                                {
                                    otherLineFinish = false;
                                    stepnum = 1100;
                                }
                            }
                            break;
                        case 1020:
                            if (!PauseFlag)
                            {
                                if (imageCalcFinishFlag)
                                {
                                    var arr = VisionResultList.ToArray();
                                    int failIndex = -1;
                                    for (int i = 0; i < arr.Length; i++)
                                    {
                                        if (arr[i].result != VResult.PASS)
                                        {
                                            failIndex = i;
                                            break;
                                        }
                                    }
                                    if (failIndex >= 0)
                                    {
                                        aggregator.SendMessage("LineFail1", "Run");
                                        imageFailDone = false;
                                        if (pLC.Connected)
                                        {
                                            pLC.WriteMCoil(2560, true);
                                        }
                                        addMessage($"{arr[failIndex].r_name}:视觉异常");
                                        System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                        {
                                            DialogParameters param = new DialogParameters();
                                            param.Add("PointName", arr[failIndex].r_name);
                                            param.Add("Image", arr[failIndex].r_image.CopyObj(1, -1));
                                            _dialogService.Show("VisionAlarmDialog", param, arg =>
                                            {
                                                imageFailDone = true;
                                            });
                                        }));
                                        stepnum = 1021;
                                    }
                                    else
                                    {
                                        aggregator.SendMessage("LineFinish1", "Run");
                                        stepnum = 1008;
                                    }
                                }
                            }
                            break;
                        case 1021:
                            if (!PauseFlag)
                            {
                                if (imageFailDone)
                                {
                                    imageFailDone = false;
                                    if (pLC.Connected)
                                    {
                                        pLC.WriteMCoil(2560, false);
                                    }
                                    stepnum = 1022;
                                }
                            }
                            break;

                        case 1022:
                            if (!PauseFlag)
                            {
                                GTSCard.AxisPosMove(ref axisX, initPoint.X, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisY, initPoint.Y, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisZ, initPoint.Z, mzRunSpeed);
                                stepnum = 1023;
                            }
                            break;
                        case 1023:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY)
                                    && GTSCard.AxisPosMoveCheckDone(axisZ))
                                {
                                    aggregator.SendMessage($"FinishCount1;999", "Run");
                                    stepnum = 1024;
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisX, 0);
                                GTSCard.AxisStop(axisY, 0);
                                GTSCard.AxisStop(axisZ, 0);
                                stepnum = 1022;
                            }
                            break;
                        case 1024:
                            if (!PauseFlag)
                            {
                                if (otherFinishCount == 999)
                                {
                                    pLC.WriteMCoil(2578, true);
                                    pLC.WriteMCoil(2570, true);
                                    pLC.WriteMCoil(2571, true);
                                    pLC.WriteMCoil(2552, true);
                                    addMessage("工作结束:视觉异常");
                                    stepnum = 9;
                                }
                            }
                            break;
                        #endregion
                        #region 跑点
                        case 1100:
                            if (!PauseFlag)
                            {
                                finishCount = 0;

                                pcsQueue.Clear();
                                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                                var points = mdb.XYZRPoints.Where(p => p.Hand == 0).OrderBy(p => p.PcsOrder);
                                if (points.Any())
                                {
                                    points.ToList().ForEach(p =>
                                    {
                                        pcsQueue.Enqueue(p);
                                    });
                                }
                                weldPointsCount = pcsQueue.Count();
                                var _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "IsZControlStudy");
                                if (_mParam != null)
                                {
                                    if (bool.TryParse(_mParam.Value, out var _v))
                                    {
                                        isZControlStudy = _v;
                                    }                                   
                                }
                                if (pLC.Connected && weldPointsCount > 0)
                                {
                                    pLC.WriteYCoil(17, true);
                                }
                                stepnum = 11101;
                            }
                            break;

                        case 11101:
                            {
                                if (pcsQueue.TryPeek(out var _pcs))
                                {
                                    curPoint = _pcs;
                                    if (curPoint.IsUse)
                                    {
                                        stepnum = 11102;
                                    }
                                    else
                                    {
                                        stepnum = 1101;
                                    }
                                }
                                else
                                {
                                    stepnum = 1101;
                                }
                            }
                            break;
                        case 11102://先跑过去
                            if (!PauseFlag)
                            {
                                GTSCard.AxisPosMove(ref axisX, curPoint.X, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisY, curPoint.Y, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisZ, mz1SafePos, mzRunSpeed);
                                stepnum = 11103;
                            }
                            break;
                        case 11103:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY) && GTSCard.AxisPosMoveCheckDone(axisZ))
                                {
                                    stepnum = 1101;
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisX, 0);
                                GTSCard.AxisStop(axisY, 0);
                                GTSCard.AxisStop(axisZ, 0);
                                stepnum = 11102;
                            }
                            break;
                  
                        case 1101:
                            {
                                if (pcsQueue.TryPeek(out var _pcs))
                                {
                                    curPoint = pcsQueue.Dequeue();
                                    ipg_power = 0;
                                    dMarkSpeed = 0;
                                    lzDist = mbornH;
                                
                                    stepnum = 1102;
                                }
                                else
                                {
                                    aggregator.SendMessage($"FinishCount1;999", "Run");
                                    if (pLC.Connected)
                                    {
                                        pLC.WriteYCoil(17, false);
                                    }
                                    stepnum = 1200;
                                    //完成
                                }
                            }
                            break;
                        case 1102:
                            if (!PauseFlag)
                            {
                                

                                if (finishCount <= otherFinishCount &&
                                    (!systemParam.IsUseVision || !curPoint.IsUse || VisionResultList.Count > 0))
                                {
                                    vresult = VResult.Null;
                                    vx1 = 0;
                                    vy1 = 0;
                                    if (curPoint.IsUse)
                                    {
                                        if (systemParam.IsUseVision)
                                        {
                                            var vp = VisionResultList.FirstOrDefault(p => p.PcsOrder == curPoint.PcsOrder);
                                            if (vp != null)
                                            {
                                                vresult = vp.result;
                                                if (vp.result == VResult.PASS)
                                                {
                                                    vx1 = vp.deltaX;
                                                    vy1 = vp.deltaY;
                                                    stepnum = 1105;
                                                }
                                                else
                                                {
                                                    imageFailDone = false;
                                                    if (pLC.Connected)
                                                    {
                                                        pLC.WriteMCoil(2560, true);
                                                    }
                                                    //视觉处理失败的
                                                    System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                                    {
                                                        DialogParameters param = new DialogParameters();
                                                        param.Add("PointName", curPoint.Name);
                                                        param.Add("Image", vp.r_image.CopyObj(1, -1));
                                                        _dialogService.Show("VisionAlarmDialog", param, arg =>
                                                        {
                                                            if (arg.Result == ButtonResult.Yes)
                                                            {
                                                                try
                                                                {
                                                                    var row = arg.Parameters.GetValue<HTuple>("row");
                                                                    var column = arg.Parameters.GetValue<HTuple>("column");
                                                                    using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                                                                    var visionPcs = mdb.VisionPoints.FirstOrDefault(v => v.Hand == 0 && v.PcsOrder == curPoint.PcsOrder);
                                                                    if (visionPcs != null)
                                                                    {
                                                                        HTuple _calc_qx, _calc_qy;
                                                                        if (visionPcs.CameraHand == 0)
                                                                        {
                                                                            HOperatorSet.AffineTransPoint2d(calibHomMat2D1, visionPcs.Rec1Row1 + row, visionPcs.Rec1Column1 + column, out _calc_qx, out _calc_qy);
                                                                        }
                                                                        else
                                                                        {
                                                                            HOperatorSet.AffineTransPoint2d(calibHomMat2D2, visionPcs.Rec1Row1 + row, visionPcs.Rec1Column1 + column, out _calc_qx, out _calc_qy);
                                                                        }
                                                                        var calibPoint = visionPcs.CameraHand == 0 ? systemParam.LeftCameraCalib : systemParam.RightCameraCalib;
                                                                        var flypoint = mdb.FlyGrabPoints.FirstOrDefault(fly => fly.Hand == visionPcs.CameraHand && fly.Kind == visionPcs.ImageKind && fly.Track == visionPcs.Track && fly.PcsOrder == visionPcs.ImagePcsOrder);
                                                                        if (flypoint != null)
                                                                        {
                                                                            var calc_qx = _calc_qx + flypoint.X - calibPoint.X;
                                                                            var calc_qy = _calc_qy + flypoint.Y - calibPoint.Y;
                                                                            double deltaX = (curPoint.X - calc_qx.D) * -1;
                                                                            double deltaY = (curPoint.Y - calc_qy.D) * -1;
                                                                            if (Math.Abs(deltaX) > vxyLimit || Math.Abs(deltaY) > vxyLimit)
                                                                            {
                                                                                vresult = VResult.Limit;
                                                                                vx1 = 0;
                                                                                vy1 = 0;
                                                                                addMessage($"手动{curPoint.Name}偏差超限! ΔX{deltaX:f1}mm,ΔY{deltaY:f1}mm");
                                                                            }
                                                                            else
                                                                            {
                                                                                vresult = VResult.PASS;
                                                                                vx1 = deltaX;
                                                                                vy1 = deltaY;
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                                catch (Exception ex)
                                                                {
                                                                    addMessage(ex.Message);
                                                                }

                                                            }
                                                            imageFailDone = true;
                                                        });
                                                    }));
                                                    stepnum = 11105;
                                                }

                                                System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                                {
                                                    try
                                                    {
                                                        CameraIamge0 = new HImage(vp.r_image.CopyObj(1, -1));
                                                        if (vp.result == VResult.PASS)
                                                        {
                                                            HOperatorSet.GenCrossContourXld(out var cross1, vp.r_baserow, vp.r_basecolumn, 24, 0);
                                                            CameraGCStyle0 = new Tuple<string, object>("Color", "red");
                                                            CameraAppendHObject0 = cross1;

                                                            HOperatorSet.GenCrossContourXld(out var cross, vp.r_row, vp.r_column, 24, 0);
                                                            CameraGCStyle0 = new Tuple<string, object>("Color", "green");
                                                            CameraAppendHObject0 = cross;
                                                            CameraAppendHMessage0 = new HMsgEntry($"{curPoint.Name}\nΔX:{vp.deltaX:f3}mm\nΔY:{vp.deltaY:f3}mm\nΔR:{vp.deltaAngle:f2}°",
                                                                40, 40, "orange red", "window", "box", "false", 24, "mono", "true", "false");
                                                        }
                                                    }
                                                    catch { }
                                                }));
                                            }
                                            else
                                            {
                                                CameraIamge0 = null;
                                                addMessage($"{curPoint.Name} 视觉未设置");
                                                stepnum = 1105;
                                            }
                                        }
                                        else
                                            stepnum = 1105;
                                    }
                                    else
                                    {
                                        stepnum = 1105;
                                    }
                                }
                            }
                            break;
                        case 11105://先运动，避免两头过近
                            if (!PauseFlag)
                            {
                                GTSCard.AxisPosMove(ref axisX, curPoint.X + curPoint.X1, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisY, curPoint.Y + curPoint.Y1, mxYRunSpeed);
                                stepnum = 11106;
                            }
                            break;
                        case 11106:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY))
                                {
                                    stepnum = 11107;
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisX, 0);
                                GTSCard.AxisStop(axisY, 0);
                                stepnum = 11105;
                            }
                            break;
                        case 11107:
                            if (!PauseFlag)
                            {
                                if (imageFailDone)
                                {
                                    imageFailDone = false;
                                    if (pLC.Connected)
                                    {
                                        pLC.WriteMCoil(2560, false);
                                    }
                                    stepnum = 1105;
                                }
                            }
                            break;
                        case 1105:
                            if (!PauseFlag)
                            {
                                GTSCard.AxisPosMove(ref axisX, curPoint.X + vx1 + curPoint.X1, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisY, curPoint.Y + vy1 + curPoint.Y1, mxYRunSpeed);
                                stepnum = 1106;
                            }
                            break;
                        case 1106:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY))
                                {
                                    if (curPoint.IsUse)
                                    {
                                        stepnum = 1107;
                                    }
                                    else
                                    {
                                        stepnum = 1120;
                                    }
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisX, 0);
                                GTSCard.AxisStop(axisY, 0);
                                stepnum = 1105;
                            }
                            break;
                        case 1107:
                            if (!PauseFlag)
                            {
                                double acc = axisZ.Acc * systemParam.AccMul;
                                GTSCard.AxisPosMove(ref axisZ, curPoint.Z, mzRunSpeed, acc);
                                stepnum = 11108;
                            }
                            break;
                        case 11108:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisZ))
                                {
                                    double curAEnc = GTSCard.GetEnc(0, 9) / 1000;
                                    double curH = lzDist = mbornH - curAEnc;
                                    double deltaH = curPoint.H - curH;
                                    bool zOK = true;
                                    double diffV1 = 0;
                                    if (isZControlStudy && VehicleBarcode != string.Empty)
                                    {
                                        //学习点位
                                        using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                                        var zpoint = mdb.ZControlPoints.FirstOrDefault(z => z.Hand == 0 && z.Barcode == VehicleBarcode && z.PcsOrder == curPoint.PcsOrder);
                                        if (zpoint != null)
                                        {
                                            zpoint.ZPos = Math.Round(GTSCard.GetEnc(axisZ), 3);
                                            zpoint.Dist = Math.Round(curAEnc, 3);
                                            zpoint.UpLimit = zDistUpLimit;
                                            zpoint.LowLimit = zDistLowLimit;
                                        }
                                        else
                                        {
                                            mdb.ZControlPoints.Add(new ZControlPoint {
                                                Barcode = VehicleBarcode,
                                                Hand = 0,
                                                PcsOrder = curPoint.PcsOrder,
                                                Name = curPoint.Name,
                                                ZPos = Math.Round(GTSCard.GetEnc(axisZ), 3),
                                                Dist = Math.Round(curAEnc, 3),
                                                UpLimit = zDistUpLimit,
                                                LowLimit = zDistLowLimit
                                            });
                                        }
                                        mdb.SaveChanges();
                                    }
                                    else
                                    {                                        
                                        if (isDoubleAlBarControl)
                                        {
                                            //比较Z轴高度
                                            using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                                            var zpoint = mdb.ZControlPoints.FirstOrDefault(z => z.Hand == 0 && z.Barcode == VehicleBarcode && z.PcsOrder == curPoint.PcsOrder);
                                            if (zpoint != null)
                                            {
                                                var _deltaZ = (zpoint.ZPos - GTSCard.GetEnc(axisZ)) * -1;
                                                var _deltaH = (zpoint.Dist - _deltaZ - curAEnc) * -1;
                                                diffV1 = _deltaH;
                                                if (_deltaH > zpoint.UpLimit)
                                                {
                                                    //压多了
                                                    zOK = false;
                                                }
                                                else if (_deltaH < zpoint.LowLimit)
                                                {
                                                    //压少了
                                                    zOK = false;
                                                }
                                            }
                                            else
                                            {
                                                //没查到
                                                zOK = false;
                                            }
                                        }
                                    }

                                    if (zOK && (vresult == VResult.PASS || !systemParam.IsUseVision))
                                    {
                                        double zTargetPos = GTSCard.GetEnc(axisZ) + deltaH;
                                        GTSCard.AxisPosMove(ref axisZ, zTargetPos, mzRunSpeed, axisZ.Acc * systemParam.AccMul);
                                        
                                        stepnum = 11109;
                                    }
                                    else
                                    {
                                        if (!zOK)
                                        {
                                            string alarmstr = $"点{curPoint.Name}高度偏:{diffV1:F3}mm,超限";
                                            addMessage(alarmstr);
                                            imageFailDone = false;
                                            if (pLC.Connected)
                                            {
                                                pLC.WriteMCoil(2560, true);
                                            }
                                            System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                            {
                                                DialogParameters param = new DialogParameters();
                                                param.Add("Message", alarmstr + "\n按\"启动\"焊接，按\"复位\"不焊。");
                                                _dialogService.Show("MessageAlarmDialog", param, arg =>
                                                {
                                                    if (arg.Result == ButtonResult.Yes)
                                                    {
                                                        alarmDialogResult = 1;
                                                    }
                                                    else
                                                    {
                                                        alarmDialogResult = 0;
                                                    }
                                                    imageFailDone = true;
                                                });
                                            }));
                                            stepnum = 11120;
                                        }
                                        else
                                            stepnum = 1110;//视觉失败的
                                    }
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisZ, 0);
                                stepnum = 1107;
                            }
                            break;
                        case 11120:
                            if (imageFailDone)
                            {
                                if (pLC.Connected)
                                {
                                    pLC.WriteMCoil(2560, false);
                                }
                                if (alarmDialogResult == 1)
                                {
                                    double curAEnc = GTSCard.GetEnc(0, 9) / 1000;
                                    double curH = lzDist = mbornH - curAEnc;
                                    double deltaH = curPoint.H - curH;
                                    double zTargetPos = GTSCard.GetEnc(axisZ) + deltaH;
                                    GTSCard.AxisPosMove(ref axisZ, zTargetPos, mzRunSpeed, axisZ.Acc * systemParam.AccMul);

                                    stepnum = 11109;
                                }
                                else
                                {
                                    stepnum = 1110;
                                }
                            }
                            break;
                        case 11109:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisZ))
                                {
                                    sw.Restart();
                                    stepnum = 1108;
                                }
                            }
                            break;
                        case 1108:
                            if (!PauseFlag)
                            {
                                if (sw.Elapsed.TotalSeconds >= preDelay)
                                {
                                    sw.Stop();
                                    if (systemParam.IsSimulate)
                                    {
                                        sw.Restart();
                                    }
                                    else
                                    {
                                        LazerDone = false;
                                        ipg_power = 0;
                                        Task.Run(() =>
                                        {
                                            dMarkSpeed = 0;

                                            switch (systemParam.LazerDevIndex)
                                            {
                                                case 1:
                                                    {
                                                        GTSCard.SetDo(axisX.CardNo, (short)(2 + curPoint.LazerDocumentIndex), 0);
                                                        while (true)
                                                        {
                                                            if (GTSCard.GetDi(axisX.CardNo, 0))
                                                            {
                                                                GTSCard.SetDo(axisX.CardNo, (short)(2 + curPoint.LazerDocumentIndex), 1);
                                                                dMarkSpeed = speedLimit[curPoint.LazerDocumentIndex, 0];
                                                                break;
                                                            }
                                                            System.Threading.Thread.Sleep(100);
                                                        }
                                                    }
                                                    break;
                                                default:
                                                case 0:
                                                    {
                                                        var str = MFunc.LazerScript(systemParam.LeftWeldIP, $"Start:{curPoint.LazerDocumentIndex}");
                                                        var strs = str.Split(new char[] { ':' });
                                                        if (strs.Length >= 2)
                                                        {
                                                            if (double.TryParse(strs[1], out var v))
                                                            {
                                                                dMarkSpeed = v;
                                                            }
                                                        }
                                                    }
                                                    break;
                                            }


                                        }).ContinueWith(arg => LazerDone = true);

                                    }
                                    if (pLC.Connected)
                                    {
                                        pLC.WriteYCoil(16, true);
                                    }
                                    s1 = new LineSeries { LineStyle = LineStyle.Solid, Color = OxyColors.SpringGreen, TrackerFormatString = "{4:f0}瓦" };
                                    plotIndex = 0;
                                    stepnum = 1109;
                                }
                            }
                            break;
                        case 1109:
                            if (!PauseFlag)
                            {
                                if ((systemParam.IsSimulate && sw.Elapsed.TotalMilliseconds > 600) || (!systemParam.IsSimulate && LazerDone))
                                {
                                    PlotModel1.Series.Clear();
                                    PlotModel1.Series.Add(s1);
                                    PlotModel1.InvalidatePlot(true);
                                    sw.Stop();
                                    if (pLC.Connected)
                                    {
                                        pLC.WriteYCoil(16, false);
                                    }
                                    LazerDone = false;
                                    double lzH = Math.Round(GTSCard.GetEnc(0, 9) / 1000, 3);//测高
                                    lzDist = Math.Round(mbornH - lzH, 3);//焦距
                                    addMessage($"点{curPoint.Name}:功率:{ipg_power} W,速度:{dMarkSpeed} mm/s,测高:{lzH}mm,焦距:{lzDist}mm,视觉:{vresult}:ΔX:{vx1:f3}mm,ΔY:{vy1:f3}mm");
                                    System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                    {
                                        aggregator.SendMessage($"Select;{curPoint.Id}", "Run");
                                    }));

                                    stepnum = 1110;
                                }
                                else
                                {
                                    var adcv = GTSCard.GetAdc(1);
                                    var powercur = Math.Round(adcv / 4 * 1000 - systemParam.LeftPowerBase, 0);
                                    if (powercur > ipg_power)
                                    {
                                        ipg_power = powercur;
                                    }
                                    s1.Points.Add(new DataPoint(plotIndex++, powercur));
                                }
                            }
                            break;
                        case 1110:
                            if (!PauseFlag)
                            {
                                double acc = axisZ.Acc * systemParam.AccMul;
                                if (mz1UpDist < 15)
                                {
                                    mz1UpDist = 15;
                                }
                                GTSCard.AxisPosMove(ref axisZ, curPoint.Z + mz1UpDist, mzRunSpeed, acc);
                                stepnum = 1111;
                            }
                            break;
                        case 1111:
                            if (!PauseFlag)
                            {
                                if ((finishCount < weldPointsCount - 1 && (GTSCard.GetEnc(axisZ) - curPoint.Z) > (mz1UpDist / 3 * 2)) || (finishCount >= weldPointsCount - 1 && GTSCard.AxisPosMoveCheckDone(axisZ)))
                                {
                                    //上下限报警弹框
                                    if (!systemParam.IsSimulate && (ipg_power > powerLimit[curPoint.LazerDocumentIndex,1] || ipg_power < powerLimit[curPoint.LazerDocumentIndex, 2] ||
                                        dMarkSpeed > speedLimit[curPoint.LazerDocumentIndex, 1] || dMarkSpeed < speedLimit[curPoint.LazerDocumentIndex, 2] ||
                                        lzDist > focalLengthLimit[curPoint.LazerDocumentIndex, 1] || lzDist < focalLengthLimit[curPoint.LazerDocumentIndex, 2]))
                                    {
                                        string alarmstr = $"{curPoint.Name}:上下限报警!\n";

                                        if (ipg_power > powerLimit[curPoint.LazerDocumentIndex, 1])
                                        {
                                            alarmstr += $"功率超上限:{ipg_power}W > {powerLimit[curPoint.LazerDocumentIndex, 1]}W\n";
                                        }
                                        if (ipg_power < powerLimit[curPoint.LazerDocumentIndex, 2])
                                        {
                                            alarmstr += $"功率超下限:{ipg_power}W < {powerLimit[curPoint.LazerDocumentIndex, 2]}W\n";
                                        }

                                        if (dMarkSpeed > speedLimit[curPoint.LazerDocumentIndex, 1])
                                        {
                                            alarmstr += $"速度超上限:{dMarkSpeed}mm/s > {speedLimit[curPoint.LazerDocumentIndex, 1]}mm/s\n";
                                        }
                                        if (dMarkSpeed < speedLimit[curPoint.LazerDocumentIndex, 2])
                                        {
                                            alarmstr += $"速度超下限:{dMarkSpeed}mm/s < {speedLimit[curPoint.LazerDocumentIndex, 2]}mm/s\n";
                                        }

                                        if (lzDist > focalLengthLimit[curPoint.LazerDocumentIndex, 1])
                                        {
                                            alarmstr += $"焦距超上限:{lzDist}mm > {focalLengthLimit[curPoint.LazerDocumentIndex, 1]}mm\n";
                                        }
                                        if (lzDist < focalLengthLimit[curPoint.LazerDocumentIndex, 2])
                                        {
                                            alarmstr += $"焦距超下限:{lzDist}mm < {focalLengthLimit[curPoint.LazerDocumentIndex, 2]}mm\n";
                                        }
                                        imageFailDone = false;
                                        if (pLC.Connected)
                                        {
                                            pLC.WriteMCoil(2560, true);
                                        }
                                        addMessage(alarmstr);
                                        System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                        {
                                            DialogParameters param = new DialogParameters();
                                            param.Add("Message", alarmstr);
                                            _dialogService.Show("MessageAlarmDialog", param, arg =>
                                            {
                                                imageFailDone = true;
                                            });
                                        }));
                                        stepnum = 1112;
                                    }
                                    else
                                    {
                                        stepnum = 1120;
                                    }
                                    if (!systemParam.IsSimulate)
                                    {
                                        #region 保存CSV
                                        var _record = new Comparison
                                        {
                                            条码 = GetBarcode(curPoint.ProductIndex),
                                            开始时间 = DateTime.Now,
                                            功率 = ipg_power,
                                            功率标准 = powerLimit[curPoint.LazerDocumentIndex, 0],
                                            功率上限 = powerLimit[curPoint.LazerDocumentIndex, 1],
                                            功率下限 = powerLimit[curPoint.LazerDocumentIndex, 2],
                                            速度 = dMarkSpeed,
                                            速度标准 = speedLimit[curPoint.LazerDocumentIndex, 0],
                                            速度上限 = speedLimit[curPoint.LazerDocumentIndex, 1],
                                            速度下限 = speedLimit[curPoint.LazerDocumentIndex, 2],
                                            焦距 = lzDist,
                                            焦距标准 = focalLengthLimit[curPoint.LazerDocumentIndex, 0],
                                            焦距上限 = focalLengthLimit[curPoint.LazerDocumentIndex, 1],
                                            焦距下限 = focalLengthLimit[curPoint.LazerDocumentIndex, 2],
                                            测高 = mbornH - lzDist,
                                            焊接点 = curPoint.Name
                                        };
                                        try
                                        {
                                            string dirpath = Path.Combine(comparisonPath, systemParam.PartList[systemParam.PartIndex], "Comparison_L");
                                            Directory.CreateDirectory(dirpath);
                                            string filename = Path.Combine(dirpath, DateTime.Now.ToString("yyyyMMdd") + "_L.csv");
                                            if (!File.Exists(filename))
                                            {
                                                using (var writer = new StreamWriter(filename))
                                                using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
                                                {
                                                    csv.WriteHeader<Comparison>();
                                                    csv.NextRecord();
                                                }
                                            }
                                            using (var stream = File.Open(filename, FileMode.Append))
                                            using (var writer = new StreamWriter(stream))
                                            using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
                                            {
                                                csv.WriteRecord(_record);
                                                csv.NextRecord();
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            addMessage(ex.Message);
                                        }
                                        #endregion
                                        #region 保存MES
                                        mesRecords.Add(_record);
                                        #endregion
                                    }
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisZ, 0);
                                stepnum = 1110;
                            }
                            break;
                        case 1112:
                            if (!PauseFlag)
                            {
                                if (imageFailDone)
                                {
                                    imageFailDone = false;
                                    if (pLC.Connected)
                                    {
                                        pLC.WriteMCoil(2560, false);
                                    }
                                    stepnum = 1120;
                                }
                            }
                            break;
                        case 1120:
                            if (!PauseFlag)
                            {
                                finishCount++;
                                aggregator.SendMessage($"FinishCount1;{finishCount}", "Run");
                                stepnum = 1101;
                            }
                            break;
                        case 1200:
                            if (!PauseFlag)
                            {
                                stepnum = 1201;
                            }
                            break;
                        case 1201:
                            if (!PauseFlag)
                            {
                                GTSCard.AxisPosMove(ref axisX, initPoint.X, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisY, initPoint.Y, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisZ, initPoint.Z, mzRunSpeed);
                                stepnum = 1202;
                            }
                            break;
                        case 1202:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY)
                                    && GTSCard.AxisPosMoveCheckDone(axisZ))
                                {
                                    stepnum = 1203;
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisX, 0);
                                GTSCard.AxisStop(axisY, 0);
                                GTSCard.AxisStop(axisZ, 0);
                                stepnum = 1201;
                            }
                            break;
                        case 1203:
                            if (!PauseFlag)
                            {
                                if (otherFinishCount == 999)
                                {
                                    stepnum = 9;
                                    
                                    pLC.WriteMCoil(2578, true);
                                    pLC.WriteMCoil(2570, true);
                                    pLC.WriteMCoil(2571, true);
                                    pLC.WriteMCoil(2552, true);
                                    addMessage("工作结束");
                                    #region 计数
                                    CycleTime = Math.Round(ctsw.Elapsed.TotalSeconds, 1);
                                    ctsw.Stop();
                                    DXH.Ini.DXHIni.WritePrivateProfileString("System", "CycleTime", CycleTime.ToString(), System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Count.ini"));
                                    CurCounter++;
                                    TotalCounter++;
                                    DXH.Ini.DXHIni.WritePrivateProfileString("System", "CurCounter", CurCounter.ToString(), System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Count.ini"));
                                    DXH.Ini.DXHIni.WritePrivateProfileString("System", "TotalCounter", TotalCounter.ToString(), System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Count.ini"));
                                    #endregion

                                    for (int i = 0; i < getBarcodeService.Barcodes.Length; i++)
                                    {
                                        aggregator.SendMessage($"UPLOAD;{GetBarcode(i)};{CurCounter};{CycleTime * 1000:f0}", "OEE");
                                    }
                                    string jsonString = JsonConvert.SerializeObject(mesRecords, Formatting.Indented);
                                    aggregator.SendMessage($"UpLoad;{jsonString};{CycleTime:f1}", "MES");
                                }
                            }
                            break;
                        #endregion
                        default:
                            break;
                    }
                    #endregion
                }
                catch { }
                #region 更新界面
                if (cycleCount++ > 100)
                {
                    cycleCount = 0;
                    StepNum = stepnum;
                    try
                    {
                        var _banci = DateTime.Now.ToString("yyyy-MM-dd");
                        if (_banci != Banci)
                        {
                            Banci = _banci;
                            addMessage("换班数据清零");
                            string filename = Path.Combine(comparisonPath, "产量统计.csv");
                            if (!File.Exists(filename))
                            {
                                using (var writer = new StreamWriter(filename))
                                using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
                                {
                                    csv.WriteHeader<ProductionStatistic>();
                                    csv.NextRecord();
                                }
                            }
                            using (var stream = File.Open(filename, FileMode.Append))
                            using (var writer = new StreamWriter(stream))
                            using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
                            {
                                csv.WriteRecord(new ProductionStatistic
                                {
                                    Time = DateTime.Now,
                                    CurCount = CurCounter,
                                    TotalCount = TotalCounter
                                });
                                csv.NextRecord();
                            }

                            CurCounter = 0;
                            DXH.Ini.DXHIni.WritePrivateProfileString("System", "CurCounter", "0", System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Count.ini"));
                            DXH.Ini.DXHIni.WritePrivateProfileString("System", "Banci", Banci, System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Count.ini"));
                        }
                    }
                    catch (Exception ex)
                    {
                        addMessage(ex.Message);
                    }
                }
                #endregion
                System.Threading.Thread.Sleep(10);
            }
        }
        private void GrabAction(CancellationToken token)
        {
            #region 变量
            int stepnum = 500;
            var axisX = gTSCard.A1; var axisY = gTSCard.A2; var axisZ = gTSCard.A3;
            var axisX1 = gTSCard.A5; var axisY1 = gTSCard.A6; var axisZ1 = gTSCard.A7;
            Queue<FlyGrabPoint> leftGrabPointQueue = new Queue<FlyGrabPoint>();
            Queue<FlyGrabPoint> rightGrabPointQueue = new Queue<FlyGrabPoint>();
            FlyGrabPoint leftGrabPoint = new FlyGrabPoint(), rightGrabPoint = new FlyGrabPoint();
            Stopwatch sw = new Stopwatch();
            bool leftGrabDone = false, rightGrabDone = false;
            bool leftFlyFinish = false, rightFlyFinish = false;
            FlyGrabPoint[] leftPathFlyGrabPoint = new FlyGrabPoint[0], rightPathFlyGrabPoint = new FlyGrabPoint[0];
            int[] Buf1 = new int[0], Buf2 = new int[0];
            int leftImageCount = 0, rightImageCount = 0;
            int trackCount = 0;
            #endregion
            gTSCard.ImageList.Clear();
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }
                try
                {
                    switch (stepnum)
                    {
                        #region 单拍
                        case 500:
                            if (!PauseFlag)
                            {
                                leftGrabPointQueue.Clear();
                                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                                var leftgrabpoints = mdb.FlyGrabPoints.Where(f => f.Hand == 0 && f.Kind == 0).OrderBy(f => f.PcsOrder);
                                if (leftgrabpoints.Any())
                                {
                                    leftgrabpoints.ToList().ForEach(p => {
                                        leftGrabPointQueue.Enqueue(p);
                                    });
                                }
                                rightGrabPointQueue.Clear();
                                var rightgrabpoints = mdb.FlyGrabPoints.Where(f => f.Hand == 1 && f.Kind == 0).OrderBy(f => f.PcsOrder);
                                if (rightgrabpoints.Any())
                                {
                                    rightgrabpoints.ToList().ForEach(p => {
                                        rightGrabPointQueue.Enqueue(p);
                                    });
                                }
                                stepnum = 501;
                            }
                            break;
                        case 501:
                            if (!PauseFlag)
                            {
                                if (leftGrabPointQueue.TryPeek(out var leftp) || rightGrabPointQueue.TryPeek(out var rightp))
                                {
                                    if (leftGrabPointQueue.TryPeek(out leftp))
                                    {
                                        leftGrabPoint = leftGrabPointQueue.Dequeue();
                                    }
                                    else
                                    {
                                        leftGrabPoint = new FlyGrabPoint
                                        {
                                            Id = -1,
                                            X = initPoint.X,
                                            Y = initPoint.Y,
                                            Z = initPoint.Z,
                                            UseLight1 = true,
                                            UseLight2 = true
                                        };
                                    }
                                    if (rightGrabPointQueue.TryPeek(out rightp))
                                    {
                                        rightGrabPoint = rightGrabPointQueue.Dequeue();
                                    }
                                    else
                                    {
                                        //leftGrabPoint
                                        rightGrabPoint = new FlyGrabPoint
                                        {
                                            Id = -1,
                                            X = rightInitPoint.X,
                                            Y = rightInitPoint.Y,
                                            Z = rightInitPoint.Z,
                                            UseLight1 = true,
                                            UseLight2 = true
                                        };
                                    }
                                    stepnum = 502;
                                }
                                else
                                {
                                    stepnum = 600;
                                }
                            }
                            break;
                        case 502:
                            if (!PauseFlag)
                            {
                                GTSCard.SetDo(axisX.CardNo, 7, (short)(leftGrabPoint.UseLight1 ? 0 : 1));
                                GTSCard.SetDo(axisX.CardNo, 8, (short)(leftGrabPoint.UseLight2 ? 0 : 1));
                                GTSCard.AxisPosMove(ref axisX, leftGrabPoint.X, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisY, leftGrabPoint.Y, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisZ, leftGrabPoint.Z, mzRunSpeed);
                                GTSCard.SetDo(axisX.CardNo, 14, (short)(rightGrabPoint.UseLight1 ? 0 : 1));
                                GTSCard.SetDo(axisX.CardNo, 15, (short)(rightGrabPoint.UseLight2 ? 0 : 1));
                                GTSCard.AxisPosMove(ref axisX1, rightGrabPoint.X, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisY1, rightGrabPoint.Y, mxYRunSpeed);
                                GTSCard.AxisPosMove(ref axisZ1, rightGrabPoint.Z, mzRunSpeed);
                                stepnum = 503;
                            }
                            break;
                        case 503:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY)
                                 && GTSCard.AxisPosMoveCheckDone(axisZ) &&
                                 GTSCard.AxisPosMoveCheckDone(axisX1) && GTSCard.AxisPosMoveCheckDone(axisY1)
                                 && GTSCard.AxisPosMoveCheckDone(axisZ1))
                                {
                                    sw.Restart();
                                    stepnum = 504;
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisX, 0);
                                GTSCard.AxisStop(axisY, 0);
                                GTSCard.AxisStop(axisZ, 0);
                                GTSCard.AxisStop(axisX1, 0);
                                GTSCard.AxisStop(axisY1, 0);
                                GTSCard.AxisStop(axisZ1, 0);
                                stepnum = 502;
                            }
                            break;
                        case 504:
                            if (!PauseFlag)
                            {
                                if (sw.Elapsed.TotalSeconds > flyPreDelay)
                                {
                                    stepnum = 505;
                                }
                            }
                            break;
                        case 505:
                            if (!PauseFlag)
                            {
                                if (leftGrabPoint.Id > 0)
                                {
                                    leftGrabDone = false;
                                    leftCamera.ImageQueue.Clear();
                                    leftCamera.SetTriggerMode(0);
                                    leftCamera.SetExposureTime((float)leftCameraExposureTime);
                                    leftCamera.StartGrabe();
                                    Task.Run(() => {
                                        int mIndex = 0;
                                        while (mIndex < 1)
                                        {
                                            HObject? hObj;
                                            if (leftCamera.ImageQueue.TryPeek(out hObj))
                                            {
                                                leftCamera.ImageQueue.TryDequeue(out hObj);
                                                gTSCard.ImageList.Add(new FlyImage
                                                {
                                                    CameraHand = 0,
                                                    MImage = hObj,
                                                    Track = 0,
                                                    ImagePcsOrder = leftGrabPoint.PcsOrder,
                                                    Kind = leftGrabPoint.Kind
                                                });
                                                mIndex++;
                                            }
                                        }
                                    }).ContinueWith(t => { leftCamera.StopGrabe(); leftGrabDone = true; });
                                }
                                else
                                {
                                    leftGrabDone = true;
                                }
                                if (rightGrabPoint.Id > 0)
                                {
                                    rightGrabDone = false;
                                    rightCamera.ImageQueue.Clear();
                                    rightCamera.SetTriggerMode(0);
                                    rightCamera.SetExposureTime((float)rightCameraExposureTime);
                                    rightCamera.StartGrabe();
                                    Task.Run(() => {
                                        int mIndex = 0;
                                        while (mIndex < 1)
                                        {
                                            HObject? hObj;
                                            if (rightCamera.ImageQueue.TryPeek(out hObj))
                                            {
                                                rightCamera.ImageQueue.TryDequeue(out hObj);
                                                gTSCard.ImageList.Add(new FlyImage
                                                {
                                                    CameraHand = 1,
                                                    MImage = hObj,
                                                    Track = 0,
                                                    ImagePcsOrder = rightGrabPoint.PcsOrder,
                                                    Kind = rightGrabPoint.Kind
                                                });
                                                mIndex++;
                                            }
                                        }
                                    }).ContinueWith(t => { rightCamera.StopGrabe(); rightGrabDone = true; });
                                }
                                else
                                {
                                    rightGrabDone = true;
                                }
                                stepnum = 506;
                            }
                            break;
                        case 506:
                            if (leftGrabDone && rightGrabDone)
                            {
                                leftGrabDone = false;
                                rightGrabDone = false;
                                stepnum = 501;
                            }
                            break;
                        #endregion
                        #region 飞拍

                        case 600:
                            if (!PauseFlag)
                            {
                                leftFlyFinish = false; rightFlyFinish = false;
                                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);

                                var pathFlyPoints = mdb.FlyGrabPoints.Where(f => f.Hand == 0 && f.Kind == 2 && f.Track == trackCount).OrderBy(f => f.PcsOrder);
                                if (pathFlyPoints.Any())
                                {
                                    leftPathFlyGrabPoint = pathFlyPoints.ToArray();
                                    var flyPoints = mdb.FlyGrabPoints.Where(f => f.Hand == 0 && f.Kind == 1 && f.Track == trackCount).OrderBy(f => f.PcsOrder);
                                    if (flyPoints.Any())
                                    {
                                        var pointArr = flyPoints.ToArray();
                                        leftImageCount = pointArr.Length;
                                        Buf1 = new int[pointArr.Length];
                                        double cameraGrabMovSpace = pointArr[0].X > pointArr[pointArr.Length - 1].X ? mFlyGrabPreDelay / 1000 * mlineScanSpeed : mFlyGrabPreDelay / 1000 * mlineScanSpeed * -1;
                                        for (int i = 0; i < pointArr.Length; i++)
                                        {
                                            Buf1[i] = (int)((pointArr[i].X - leftPathFlyGrabPoint[0].X + cameraGrabMovSpace) / axisX.Equiv);
                                        }
                                    }
                                    else
                                    {
                                        leftImageCount = 0;
                                    }
                                }
                                else
                                {
                                    leftFlyFinish = true;
                                }

                                pathFlyPoints = mdb.FlyGrabPoints.Where(f => f.Hand == 1 && f.Kind == 2 && f.Track == trackCount).OrderBy(f => f.PcsOrder);
                                if (pathFlyPoints.Any())
                                {
                                    rightPathFlyGrabPoint = pathFlyPoints.ToArray();
                                    var flyPoints = mdb.FlyGrabPoints.Where(f => f.Hand == 1 && f.Kind == 1 && f.Track == trackCount).OrderBy(f => f.PcsOrder);
                                    if (flyPoints.Any())
                                    {
                                        var pointArr = flyPoints.ToArray();
                                        rightImageCount = pointArr.Length;
                                        Buf2 = new int[pointArr.Length];
                                        double cameraGrabMovSpace = pointArr[0].X > pointArr[pointArr.Length - 1].X ? mFlyGrabPreDelay / 1000 * mlineScanSpeed : mFlyGrabPreDelay / 1000 * mlineScanSpeed * -1;
                                        for (int i = 0; i < pointArr.Length; i++)
                                        {
                                            Buf2[i] = (int)((pointArr[i].X - rightPathFlyGrabPoint[0].X + cameraGrabMovSpace) / axisX.Equiv);
                                        }
                                    }
                                    else
                                    {
                                        rightImageCount = 0;
                                    }

                                }
                                else
                                {
                                    rightFlyFinish = true;
                                }
                                if (leftFlyFinish && rightFlyFinish)
                                {                                    
                                    return;//飞拍完成
                                }
                                else
                                {
                                    stepnum = 601;
                                }
                            }
                            break;


                        case 601:
                            if (!PauseFlag)
                            {
                                if (!leftFlyFinish)
                                {
                                    GTSCard.SetDo(axisX.CardNo, 7, (short)(leftPathFlyGrabPoint[0].UseLight1 ? 0 : 1));
                                    GTSCard.SetDo(axisX.CardNo, 8, (short)(leftPathFlyGrabPoint[0].UseLight2 ? 0 : 1));
                                    GTSCard.AxisPosMove(ref axisX, leftPathFlyGrabPoint[0].X, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisY, leftPathFlyGrabPoint[0].Y, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisZ, leftPathFlyGrabPoint[0].Z, mzRunSpeed);
                                }
                                else
                                {
                                    GTSCard.SetDo(axisX.CardNo, 7, 0);
                                    GTSCard.SetDo(axisX.CardNo, 8, 0);
                                    GTSCard.AxisPosMove(ref axisX, initPoint.X, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisY, initPoint.Y, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisZ, initPoint.Z, mzRunSpeed);
                                }
                                if (!rightFlyFinish)
                                {
                                    GTSCard.SetDo(axisX.CardNo, 14, (short)(rightPathFlyGrabPoint[0].UseLight1 ? 0 : 1));
                                    GTSCard.SetDo(axisX.CardNo, 15, (short)(rightPathFlyGrabPoint[0].UseLight2 ? 0 : 1));
                                    GTSCard.AxisPosMove(ref axisX1, rightPathFlyGrabPoint[0].X, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisY1, rightPathFlyGrabPoint[0].Y, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisZ1, rightPathFlyGrabPoint[0].Z, mzRunSpeed);
                                }
                                else
                                {
                                    GTSCard.SetDo(axisX.CardNo, 14, 0);
                                    GTSCard.SetDo(axisX.CardNo, 15, 0);
                                    GTSCard.AxisPosMove(ref axisX1, rightInitPoint.X, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisY1, rightInitPoint.Y, mxYRunSpeed);
                                    GTSCard.AxisPosMove(ref axisZ1, rightInitPoint.Z, mzRunSpeed);
                                }
                                stepnum = 602;
                            }
                            break;
                        case 602:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY)
                                 && GTSCard.AxisPosMoveCheckDone(axisZ) &&
                                 GTSCard.AxisPosMoveCheckDone(axisX1) && GTSCard.AxisPosMoveCheckDone(axisY1)
                                 && GTSCard.AxisPosMoveCheckDone(axisZ1))
                                {
                                    sw.Restart();
                                    stepnum = 603;
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisX, 0);
                                GTSCard.AxisStop(axisY, 0);
                                GTSCard.AxisStop(axisZ, 0);
                                GTSCard.AxisStop(axisX1, 0);
                                GTSCard.AxisStop(axisY1, 0);
                                GTSCard.AxisStop(axisZ1, 0);
                                stepnum = 601;
                            }
                            break;
                        case 603:
                            if (!PauseFlag)
                            {
                                if (sw.Elapsed.TotalSeconds > flyPreDelay)
                                {
                                    stepnum = 604;
                                }
                            }
                            break;
                        case 604:
                            if (!PauseFlag)
                            {
                                if (leftImageCount > 0)
                                {
                                    GTSCard.AxisCompareUse1(0, axisX.AxisId, Buf1);//设置飞拍数据

                                    leftCamera.ImageQueue.Clear();
                                    leftCamera.SetExposureTime((float)leftCameraExposureTime);
                                    leftCamera.SetTriggerMode(1);
                                    leftCamera.StartGrabe();
                                }
                                if (rightImageCount > 0)
                                {
                                    GTSCard.AxisCompareUse2(0, axisX1.AxisId, Buf2);//设置飞拍数据
                                    rightCamera.ImageQueue.Clear();
                                    rightCamera.SetExposureTime((float)rightCameraExposureTime);
                                    rightCamera.SetTriggerMode(1);
                                    rightCamera.StartGrabe();
                                }
                                stepnum = 605;
                            }
                            break;
                        case 605:
                            if (!PauseFlag)
                            {
                                if (!leftFlyFinish)
                                {
                                    GTSCard.AxisPosMove(ref axisX, leftPathFlyGrabPoint[1].X, mlineScanSpeed);
                                }
                                else
                                {
                                    GTSCard.AxisPosMove(ref axisX, initPoint.X, mxYRunSpeed);
                                }
                                if (!rightFlyFinish)
                                {
                                    GTSCard.AxisPosMove(ref axisX1, rightPathFlyGrabPoint[1].X, mlineScanSpeed);
                                }
                                else
                                {
                                    GTSCard.AxisPosMove(ref axisX1, rightInitPoint.X, mxYRunSpeed);
                                }
                                stepnum = 606;
                            }
                            break;
                        case 606:
                            if (!PauseFlag)
                            {
                                if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisX1))
                                {
                                    leftCamera.StopGrabe();
                                    rightCamera.StopGrabe();
                                    if (leftImageCount > 0)
                                    {
                                        int _index = 0;
                                        using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                                        var flyPoints = mdb.FlyGrabPoints.Where(f => f.Hand == 0 && f.Track == trackCount && f.Kind == 1).OrderBy(f => f.PcsOrder);
                                        var _arr = flyPoints.ToArray();
                                        while (leftCamera.ImageQueue.TryDequeue(out var _img))
                                        {
                                            gTSCard.ImageList.Add(new FlyImage
                                            {
                                                CameraHand = 0,
                                                MImage = _img,
                                                Track = trackCount,
                                                ImagePcsOrder = _arr[_index++].PcsOrder,
                                                Kind = 1
                                            });
                                        }
                                    }
                                    if (rightImageCount > 0)
                                    {
                                        int _index = 0;
                                        using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                                        var flyPoints = mdb.FlyGrabPoints.Where(f => f.Hand == 1 && f.Track == trackCount && f.Kind == 1).OrderBy(f => f.PcsOrder);
                                        var _arr = flyPoints.ToArray();
                                        while (rightCamera.ImageQueue.TryDequeue(out var _img))
                                        {
                                            gTSCard.ImageList.Add(new FlyImage
                                            {
                                                CameraHand = 1,
                                                MImage = _img,
                                                Track = trackCount,
                                                ImagePcsOrder = _arr[_index++].PcsOrder,
                                                Kind = 1
                                            });
                                        }
                                    }
                                    trackCount++;
                                    stepnum = 600;
                                }
                            }
                            else
                            {
                                GTSCard.AxisStop(axisX, 0);
                                GTSCard.AxisStop(axisX1, 0);
                                stepnum = 605;
                            }
                            break;
                        #endregion
                        default:
                            break;
                    }
                }
                catch(Exception ex) { addMessage(ex.Message); }
                System.Threading.Thread.Sleep(10);
            
            }
        }
        void LoadParam()
        {
            try
            {
                //Json序列化，从文件读取
                string jsonString = File.ReadAllText(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Param.json"));
                systemParam = JsonConvert.DeserializeObject<Param>(jsonString);
                Banci = DXH.Ini.DXHIni.ContentReader("System", "Banci", "Null", System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Count.ini"));
                CurCounter = Convert.ToInt32(DXH.Ini.DXHIni.ContentReader("System", "CurCounter", "0", System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Count.ini")));
                TotalCounter = Convert.ToInt32(DXH.Ini.DXHIni.ContentReader("System", "TotalCounter", "0", System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Count.ini")));
                CycleTime = Convert.ToDouble(DXH.Ini.DXHIni.ContentReader("System", "CycleTime", "0", System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Count.ini")));
            }
            catch (Exception ex)
            {
                addMessage(ex.Message);
            }
        }
        void LoadParamFromDB()
        {
            try
            {
                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                var _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "XYRunSpeed");
                if (_mParam != null)
                {
                    mxYRunSpeed = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "ZRunSpeed");
                if (_mParam != null)
                {
                    mzRunSpeed = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "ZSafePos" && m.Hand == 0);
                if (_mParam != null)
                {
                    mz1SafePos = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "ZSafePos" && m.Hand == 1);
                if (_mParam != null)
                {
                    mz2SafePos = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "ZUpDist" && m.Hand == 0);
                if (_mParam != null)
                {
                    mz1UpDist = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "LineScanSpeed");
                if (_mParam != null)
                {
                    mlineScanSpeed = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "BornH" && m.Hand == 0);
                if (_mParam != null)
                {
                    mbornH = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(p => p.Name == "PointInit" && p.Hand == 0);
                if (_mParam != null)
                {
                    initPoint = JsonConvert.DeserializeObject<MPoint>(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(p => p.Name == "PointInit" && p.Hand == 1);
                if (_mParam != null)
                {
                    rightInitPoint = JsonConvert.DeserializeObject<MPoint>(_mParam.Value);
                }

                _mParam = mdb.MParams.FirstOrDefault(p => p.Name == "PreDelay");
                if (_mParam != null)
                {
                    preDelay = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(p => p.Name == "XMinDist");
                if (_mParam != null)
                {
                    mXMinDist = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(p => p.Name == "VxyLimit");
                if (_mParam != null)
                {
                    vxyLimit = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(p => p.Name == "FlyPreDelay");
                if (_mParam != null)
                {
                    flyPreDelay = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(p => p.Name == "FlyGrabPreDelay" && p.Hand == 0);
                if (_mParam != null)
                {
                    mFlyGrabPreDelay = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(p => p.Name == "ComparisonPath");
                if (_mParam != null)
                {
                    comparisonPath = _mParam.Value;
                }
                _mParam = mdb.MParams.FirstOrDefault(p => p.Name == "ImagePath");
                if (_mParam != null)
                {
                    imagePath = _mParam.Value;
                }
                
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "ZLimit");
                if (_mParam != null)
                {
                    mZLimit = double.Parse(_mParam.Value);
                }

                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "CameraExposureTime" && m.Hand == 0);
                if (_mParam != null)
                {
                    leftCameraExposureTime = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "CameraExposureTime" && m.Hand == 1);
                if (_mParam != null)
                {
                    rightCameraExposureTime = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "ZDistUpLimit");
                if (_mParam != null)
                {
                    zDistUpLimit = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "ZDistLowLimit");
                if (_mParam != null)
                {
                    zDistLowLimit = double.Parse(_mParam.Value);
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "IsVisionResultConfirm");
                if (_mParam != null)
                {
                    if (bool.TryParse(_mParam.Value, out var v1))
                    {
                        isVisionResultConfirm = v1;
                    }
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "IsCameraScanBarcode");
                if (_mParam != null)
                {
                    if (bool.TryParse(_mParam.Value, out var v1))
                    {
                        isCameraScanBarcode = v1;
                    }
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "IsDoubleAlBarControl");
                if (_mParam != null)
                {
                    if (bool.TryParse(_mParam.Value, out var v1))
                    {
                        isDoubleAlBarControl = v1;
                    }
                }
                _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "VehicleBarcode");
                if (_mParam != null)
                {
                    VehicleBarcode = _mParam.Value;
                }
                else
                {
                    VehicleBarcode = string.Empty;
                    mdb.MParams.Add(new MParam {
                        Name = "VehicleBarcode",
                        Value = VehicleBarcode,
                        Type = typeof(string).Name,
                        Hand = 0
                    });
                    mdb.SaveChanges();
                }                

                var _limitParams = mdb.ParamScales.Where(p => p.Hand == 0);
                if (_limitParams.Any())
                {
                    for (int i = 0; i < 5; i++)
                    {
                        var _power = _limitParams.FirstOrDefault(v => v.Name == "Power" && v.LazerDocumentIndex == i);
                        if (_power != null)
                        {
                            powerLimit[i, 0] = _power.PValue;
                            powerLimit[i, 1] = _power.UpLimit;
                            powerLimit[i, 2] = _power.DownLimit;
                        }
                        var _speed = _limitParams.FirstOrDefault(v => v.Name == "Speed" && v.LazerDocumentIndex == i);
                        if (_speed != null)
                        {
                            speedLimit[i, 0] = _speed.PValue;
                            speedLimit[i, 1] = _speed.UpLimit;
                            speedLimit[i, 2] = _speed.DownLimit;
                        }
                        var _focalLength = _limitParams.FirstOrDefault(v => v.Name == "FocalLength" && v.LazerDocumentIndex == i);
                        if (_focalLength != null)
                        {
                            focalLengthLimit[i, 0] = _focalLength.PValue;
                            focalLengthLimit[i, 1] = _focalLength.UpLimit;
                            focalLengthLimit[i, 2] = _focalLength.DownLimit;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                addMessage(ex.Message);
            }
        }
        void LoadCameraParam()
        {
            try
            {
                string calibfilepath1 = "Camera\\Calib\\Left";
                string calibfilepath2 = "Camera\\Calib\\Right";

                HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, calibfilepath1, "CalibHomMat2D.tup"), out calibHomMat2D1);

                HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, calibfilepath2, "CalibHomMat2D.tup"), out calibHomMat2D2);

            }
            catch (Exception ex)
            {
                addMessage(ex.Message);
            }
        }        
        private void XHome(CancellationToken token)
        {
            int stepnum = 0;
            var axisX = gTSCard.A1;
            int actionCount = 0;
            addMessage("X轴回原点中");
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }
                switch (stepnum)
                {
                    case 0:
                        if (!XHomed)
                        {
                            stepnum = 3;
                        }
                        else
                        {
                            addMessage("X轴已回原点");
                            return;
                        }
                        break;
                    case 3:
                        if (!PauseFlag)
                        {
                            GTSCard.AxisHomeMove(axisX);
                            stepnum = 4;
                        }
                        break;
                    case 4:
                        if (!PauseFlag)
                        {
                            if (GTSCard.AxisHomeCheckDone(axisX))
                            {
                                actionCount++;
                                if (actionCount > 1)
                                {
                                    System.Threading.Thread.Sleep(2000);
                                    GTSCard.AxisZeroSet(axisX);
                                    GTSCard.AxisPosSet(axisX, systemParam.LeftDelta.X);
                                    GTSCard.AxisEncSet(axisX, systemParam.LeftDelta.X);
                                    GTSCard.ClearAlm1(axisX);
                                    XHomed = true;
                                    addMessage("X轴回原点完成");
                                    return;
                                }
                                else
                                {
                                    GTSCard.AxisZeroSet(axisX);
                                    GTSCard.ClearAlm1(axisX);
                                    stepnum = 3;
                                }
                            }
                        }
                        else
                        {
                            GTSCard.AxisStop(axisX, 0);
                            stepnum = 3;
                        }
                        break;
                    default:
                        break;
                }
                System.Threading.Thread.Sleep(100);
            }
        }
        private void YHome(CancellationToken token)
        {
            int stepnum = 0;
            var axisY = gTSCard.A2;
            int actionCount = 0;
            addMessage("Y轴回原点中");
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }
                switch (stepnum)
                {
                    case 0:
                        if (!YHomed)
                        {
                            stepnum = 3;
                        }
                        else
                        {
                            addMessage("Y轴已回原点");
                            return;
                        }
                        break;
                    case 3:
                        if (!PauseFlag)
                        {
                            GTSCard.AxisHomeMove(axisY);
                            stepnum = 4;
                        }
                        break;
                    case 4:
                        if (!PauseFlag)
                        {
                            if (GTSCard.AxisHomeCheckDone(axisY))
                            {
                                actionCount++;
                                if (actionCount > 1)
                                {
                                    System.Threading.Thread.Sleep(2000);
                                    GTSCard.AxisZeroSet(axisY);
                                    GTSCard.AxisPosSet(axisY, systemParam.LeftDelta.Y);
                                    GTSCard.AxisEncSet(axisY, systemParam.LeftDelta.Y);
                                    GTSCard.ClearAlm1(axisY);
                                    YHomed = true;
                                    addMessage("Y轴回原点完成");
                                    return;
                                }
                                else
                                {
                                    GTSCard.AxisZeroSet(axisY);
                                    GTSCard.ClearAlm1(axisY);
                                    stepnum = 3;
                                }
                            }
                        }
                        else
                        {
                            GTSCard.AxisStop(axisY, 0);
                            stepnum = 3;
                        }
                        break;
                    default:
                        break;
                }
                System.Threading.Thread.Sleep(100);
            }
        }
        private void ResetAction()
        {
            GTSCard.AxisStop(gTSCard.A1, 0);
            GTSCard.AxisStop(gTSCard.A2, 0);
            GTSCard.AxisStop(gTSCard.A3, 0);
            GTSCard.ServoOff(gTSCard.A1);
            GTSCard.ServoOff(gTSCard.A2);
            GTSCard.ServoOff(gTSCard.A3);
            GTSCard.SetDo(gTSCard.A1.CardNo, 0, 1);
            GTSCard.SetDo(gTSCard.A1.CardNo, 2, 1);
            GTSCard.SetDo(gTSCard.A1.CardNo, 3, 1);
            GTSCard.SetDo(gTSCard.A1.CardNo, 4, 1);
            GTSCard.SetDo(gTSCard.A1.CardNo, 5, 1);
            GTSCard.SetDo(gTSCard.A1.CardNo, 6, 1);
            GTSCard.SetDo(gTSCard.A1.CardNo, 7, 0);
            GTSCard.SetDo(gTSCard.A1.CardNo, 8, 0);
            if (pLC.Connected)
            {
                pLC.WriteYCoil(16, false);
                pLC.WriteYCoil(17, false);
            }
        }
        private string GetBarcode(int productIndex)
        {
            if (getBarcodeService.Barcodes.Length > productIndex && productIndex >= 0)
            {
                return getBarcodeService.Barcodes[productIndex].Substring(0);
            }
            else
            {
                return string.Empty;
            }
        }
        private void VisionAction(string procedureName, HObject img, HTuple dir, out HTuple row,
         out HTuple column, out HTuple angle, out HTuple result)
        {
            result = new HTuple(0);
            try
            {
                string[] strs = procedureName.Split("_");
                int id = int.Parse(strs[0]);
                HOperatorSet.RotateImage(img, out var ho_ImageRotate, (90 * dir) * -1, "constant");
                HOperatorSet.GetImageSize(ho_ImageRotate, out var hv_Width, out var hv_Height);
                HTuple hv_row = new HTuple(0), hv_column = new HTuple(0), hv_angle = new HTuple(0), hv_score = new HTuple(0), v1 = new HTuple(0), v2 = new HTuple(0);
                HObject eImage = ho_ImageRotate;
                HObject ngRegion, SelectedRegion;
                HOperatorSet.GenEmptyObj(out ngRegion);
                HOperatorSet.GenEmptyObj(out SelectedRegion);
                bool r1 = true;
                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                var projects = mdb.VisionProjects.Where(pro => pro.ProgramId == id).OrderBy(pro => pro.PcsOrder);
                if (projects.Any())
                {
                    var mprojects = projects.ToList();
                    foreach (var project in mprojects)
                    {
                        if (!r1)
                        {
                            break;
                        }
                        var _function = mdb.VisionFunctions.FirstOrDefault(func => func.Id == project.FunctionId);
                        if (_function != null)
                        {
                            r1 = MFunc.FunDictionary[_function.Name].Run(ref eImage, project.Parameter, ref hv_row, ref hv_column, ref hv_angle, ref hv_score, ref ngRegion, ref SelectedRegion, ref v1, ref v2);
                        }
                        else
                        {
                            r1 = false;
                        }
                    }

                }
                if (r1)
                {
                    result = new HTuple(1);
                    row = hv_row;
                    column = hv_column;
                    angle = hv_angle;
                    switch (dir.I)
                    {
                        case 1://90°
                            {
                                var box = row;
                                row = hv_Width - 1 - column;
                                column = box;
                            }
                            break;
                        case 2://180°
                            {
                                var box1 = row;
                                var box2 = column;
                                row = box1 * -1 + hv_Height - 1;
                                column = box2 * -1 + hv_Width - 1;
                            }
                            break;
                        case 3://270°
                            {
                                var box1 = hv_Width - 1 - column;
                                var box2 = row;
                                row = box1 * -1 + hv_Width - 1;
                                column = box2 * -1 + hv_Height - 1;
                            }
                            break;
                        default:
                            break;
                    }
                }
                else
                {
                    result = new HTuple(0);
                    row = new HTuple(0);
                    column = new HTuple(0);
                    angle = new HTuple(0);
                }
                eImage.Dispose();
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                result = new HTuple(0);
                row = new HTuple(0);
                column = new HTuple(0);
                angle = new HTuple(0);
            }

        }
        private void SaveVehicleBarcode(string bar)
        {
            try
            {
                using var mdb = new MDbContext(systemParam.PartList[systemParam.PartIndex]);
                var _mParam = mdb.MParams.FirstOrDefault(m => m.Name == "VehicleBarcode");
                if (_mParam != null)
                {
                    _mParam.Value = bar;
                    mdb.SaveChanges();
                }
            }
            catch { }
        }
        #endregion
    }
    class ProductionStatistic
    {
        public DateTime Time { get; set; }
        public int CurCount { get; set; }
        public long TotalCount { get; set; }
    }
}
